Open GoogleCodeExporter opened 9 years ago
//Draw Icon/Text,Owner Draw
void ButtonRno::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC *pCDC = CDC::FromHandle(lpDrawItemStruct->hDC);
pCDC->SetBkMode(TRANSPARENT);
CRect itemRect = lpDrawItemStruct->rcItem;
HICON hIcon = AfxGetApp() -> LoadIcon(IDI_ICON2);
pCDC->DrawState(itemRect.TopLeft(), itemRect.Size(), hIcon, DSS_NORMAL, (CBrush*)NULL);
pCDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
pCDC->DrawText(L"Rooney", -1, itemRect, DT_CENTER);
}
Original comment by Giggs...@gmail.com
on 17 Feb 2012 at 7:41
MouseOn/MouseMove:
BEGIN_MESSAGE_MAP(ButtonRno, CButton)
ON_WM_MOUSEMOVE()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
END_MESSAGE_MAP()
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
afx_msg void OnMouseMove(UINT nHitTest, CPoint point);
afx_msg void OnKillFocus(CWnd* cwnd);
afx_msg void OnSetFocus(CWnd* cwnd);
LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);
LRESULT ButtonRno::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{ CDC *pCDC = this->GetDC();
pCDC->SetBkMode(TRANSPARENT);
CRect itemRect;
this->GetClientRect(&itemRect);
HICON hIcon = AfxGetApp() -> LoadIcon(IDI_ICON2);
pCDC->DrawState(itemRect.TopLeft(), itemRect.Size(), hIcon, DSS_NORMAL, (CBrush*)NULL);
pCDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
pCDC->DrawText(L"Rooney", -1, itemRect, DT_CENTER);
return S_OK;
}
LRESULT ButtonRno::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
CDC *pCDC = this->GetDC();
pCDC->SetBkMode(TRANSPARENT);
CRect itemRect;
this->GetClientRect(&itemRect);
HICON hIcon = AfxGetApp() -> LoadIcon(IDI_ICON_MU);
pCDC->DrawState(itemRect.TopLeft(), itemRect.Size(), hIcon, DSS_NORMAL, (CBrush*)NULL);
pCDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
pCDC->DrawText(L"focused", -1, itemRect, DT_CENTER);
return S_OK;
}
void ButtonRno::OnMouseMove(UINT nHitTest, CPoint point)
{
TRACKMOUSEEVENT tme;
tme.cbSize=sizeof(TRACKMOUSEEVENT);
tme.dwFlags=TME_HOVER | TME_LEAVE;
tme.dwHoverTime=HOVER_DEFAULT;
tme.hwndTrack=m_hWnd;
if(!_TrackMouseEvent(&tme))
{
AfxMessageBox( L"鼠标事件捕捉失败! ");
}
}
Original comment by Giggs...@gmail.com
on 22 Feb 2012 at 9:31
#pragma once
#include "../../Core/Protocol/Handler.h"
#include "../../Core/Protocol/Inc/Header.h"
#include "../../Core/Common/WCLaoType.h"
void Protocol_Init(int &iHeaderSize, int &iBodyOffset, CB_MidCallback cb);
void Protocol_Dispatcher(enumNetworkOperationType t, char *pszData, size_t
stLength, bool &bServerDisconnect);
#include "stdafx.h"
#include "Handler.h"
#include "Inc/Header.h"
#include "../../Core/Debug/Debug.h"
#include "../../Core/Network/Net.h"
#include "../../Core/Common/UserInfo.h"
#include "../../Core/Console/Console.h"
static CB_MidCallback m_cb = NULL;
void Protocol_Init(int &iHeaderSize, int &iBodyOffset, CB_MidCallback cb)
{
Protocol_InfoGetSet(iHeaderSize, iBodyOffset);
m_cb = cb;
}
void Protocol_Dispatcher(enumNetworkOperationType t, char *pszData, size_t
stLength, bool &bServerDisconnect)
{
switch (t)
{
case C_LOGIN:
break;
case S_RESPONSE_LOGIN:
PrintConsoleLog(WCLao_DEBUG, "login success...");
UserInfo_SetLoginStatus(true);//loging success
m_cb(S_RESPONSE_LOGIN, NULL, 0);
break;
case S_FRIEND_LIST:
break;
case C_OPRSP_1:
PrintConsoleLog(WCLao_DEBUG, "C_OPRSP_1...X");
break;
case C_OPRSP_2:
PrintConsoleLog(WCLao_DEBUG, "C_OPRSP_2...X");
break;
case C_OPRSP_3:
PrintConsoleLog(WCLao_DEBUG, "C_OPRSP_3...X");
break;
default:
//OutputDebugInfoA("UNKOWN NETWORK OPERATION TYPE!", __FILE__, __FUNCTION__):
break;
}
if (bServerDisconnect)
{
m_cb(DROPLINE, NULL, 0);
}
}
Original comment by Giggs...@gmail.com
on 29 Jul 2013 at 2:19
#pragma once
#include "../../Core/Common/WCLaoType.h"
#include "../../Core/Network/Net.h"
//interface
//
bool MID_Login(char *pszServerIP, int iServerPort, int iUserID, char
*pwszPassword);//connect to server & login
bool MID_OP_1();
bool MID_OP_2();
bool MID_OP_3();
bool MID_Logout();
void MID_breath();
//assist func
//
void MID_Init(HWND h, CB_MidCallback cb, int iProtocolHeaderSize, int
iProtocolBodyLen);
void MID_Fini();
bool MID_StartCommunication(char *pszServerIP, int iServerPort);
void MID_StopCommunication();
#include "stdafx.h"
#include "Communication.h"
#include "../../Core/Network/Net.h"
#include "../../Core/Console/Console.h"
#include "../../Core/Debug/Debug.h"
#include "../../Core/Protocol/Inc/DataPacker.h"
#include "../../Core/Protocol/Handler.h"
#include "../../Core/Common/UserInfo.h"
static CB_MidCallback m_cb = NULL;
static void NetworkPackageHandler(char *data, int len)
{
if (!data)
{
m_cb(DROPLINE, NULL, 0);
return;
}
CommonHeader *p = (CommonHeader *)data;
bool bServerDisconnect = false;
Protocol_Dispatcher(p->enot, data, len, bServerDisconnect);
delete data;
}
void MID_Init(HWND h, CB_MidCallback cb, int iProtocolHeaderSize, int
iProtocolBodyLen)
{
m_cb = cb;
NW_Init(h, iProtocolHeaderSize, iProtocolBodyLen, (CB_NetworkPackageCallback)NetworkPackageHandler);
}
void MID_Fini()
{
NW_Fini();
}
bool MID_OP_1()
{
char *pszDataSend = NULL;
unsigned int dwLength = 0;
if (!Protocol_H_GetRequestData_OP1(pszDataSend, dwLength))
{
return false;
}
if (!NW_PostSend(pszDataSend, dwLength))
{
return false;
}
PrintConsoleLog(WCLao_INFO, "OP_1 sent");
return true;
}
bool MID_OP_2()
{
char *pszDataSend = NULL;
unsigned int dwLength = 0;
if (!Protocol_H_GetRequestData_OP2(pszDataSend, dwLength))
{
return false;
}
if (!NW_PostSend(pszDataSend, dwLength))
{
return false;
}
PrintConsoleLog(WCLao_INFO, "OP_2 sent");
return true;
}
bool MID_OP_3()
{
char *pszDataSend = NULL;
unsigned int dwLength = 0;
if (!Protocol_H_GetRequestData_OP3(pszDataSend, dwLength))
{
return false;
}
if (!NW_PostSend(pszDataSend, dwLength))
{
return false;
}
PrintConsoleLog(WCLao_INFO, "OP_3 sent");
return true;
}
bool MID_Login(char *pszServerIP, int iServerPort, int iUserID, char
*pszPassword)
{
//connect to server first
if (!MID_StartCommunication(pszServerIP, iServerPort))
{
return false;
}
//send user name & password then
char *pszDataSend = NULL;
DWORD dwLength = 0;
if (!Protocol_H_GetLoginRequestData(pszDataSend, dwLength, iUserID, pszPassword))
{
return false;
}
UserInfo_SetUserID((((struct_Login_Req_C *)(pszDataSend + SIZE_CommonHeader))->iUserID));//set user ID
if (!NW_PostSend(pszDataSend, dwLength))
{
return false;
}
PrintConsoleLog(WCLao_INFO, "login req sent");
do
{
static int time = 0;
if (UserInfo_GetLoginStatus())
{
break;
}
else
{
Sleep(1000);
time++;
if (time == 10)
{
PrintConsoleLog(WCLao_INFO, "login time out!");
return false;//time out error
}
}
}
while (true);
return true;
}
bool MID_Logout()
{
DWORD dwBytesSentCount = SIZE_CommonHeader;
char *pszDataSend = Protocol_H_GetLogoutRequestData();
if (!NW_PostSend(pszDataSend, dwBytesSentCount))
{
return false;
}
PrintConsoleLog(WCLao_INFO, "logout req sent");
return true;
}
bool MID_StartCommunication(char *pszServerIP, int iServerPort)
{
return NW_PostConnect(pszServerIP, iServerPort);
}
void MID_StopCommunication()
{
NW_DisconnectToServer();
}
void MID_breath()
{
char *pszDataSend = Protocol_H_GetBreathRequestData();
if (!NW_PostSend(pszDataSend, SIZE_CommonHeader))
{
PrintConsoleLog(WCLao_ERROR, "breath sent error!");
}
else
{
// PrintConsoleLog(WCLao_ERROR, "breath sent OK!");
}
}
bool UserInfo_GetServerAnnouncement()
{
return true;
}
Original comment by Giggs...@gmail.com
on 29 Jul 2013 at 2:20
// MainBoardDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "WCLao.h"
#include "WCLaoDlg.h"
#include "MainBoardDlg.h"
#include "WCLaoMessage.h"
#include "Core/UI/Communication.h"
#include "Core/Debug/Debug.h"
#include "PrivateChatDlg.h"
#include "Core/Console/Console.h"
static CString g_sFriendKeyTemp;
CMainBoardDlg *g_p = NULL;
static void OnDropline(enumNetworkOperationType t, char *pszData, size_t
stLength)
{
KillTimer(g_p->GetSafeHwnd(), 0);
}
// CMainBoardDlg 对话框
IMPLEMENT_DYNAMIC(CMainBoardDlg, CDialog)
CMainBoardDlg::CMainBoardDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMainBoardDlg::IDD, pParent)
{
UserInfo_Init();
}
CMainBoardDlg::~CMainBoardDlg()
{
UserInfo_Fini();
Shell_NotifyIcon(NIM_DELETE, &m_nidNotifyIcon);
}
void CMainBoardDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_STATIC_USER_NAME, m_staticUserName);
DDX_Control(pDX, IDC_STATIC_STATUS, m_staticUserStatus);
DDX_Control(pDX, IDC_TREE_FRIEND_LIST, m_tvFriendList);
DDX_Control(pDX, IDC_EDIT_Message, m_editMessage);
}
BEGIN_MESSAGE_MAP(CMainBoardDlg, CDialog)
ON_MESSAGE(WM_SWITCH_TO_MAINBOARD_WND, &CMainBoardDlg::OnSwitchToMainBoardWnd)
ON_WM_CLOSE()
ON_WM_TIMER()
ON_NOTIFY(NM_DBLCLK, IDC_TREE_FRIEND_LIST, &CMainBoardDlg::OnNMDblclkTreeFriendList)
ON_NOTIFY(NM_RCLICK, IDC_TREE_FRIEND_LIST, &CMainBoardDlg::OnNMRClickTreeFriendList)
ON_COMMAND(ID_CHAT, &CMainBoardDlg::OnChat)
ON_MESSAGE(WM_NOTIFY_ICON, &CMainBoardDlg::OnNotifyIcon)
ON_BN_CLICKED(IDC_BUTTON_MINIMIZE, &CMainBoardDlg::OnBnClickedButtonMinimize)
ON_NOTIFY(NM_CLICK, IDC_TREE_FRIEND_LIST, &CMainBoardDlg::OnNMClickTreeFriendList)
ON_BN_CLICKED(IDC_BUTTON2, &CMainBoardDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, &CMainBoardDlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON4, &CMainBoardDlg::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON5, &CMainBoardDlg::OnBnClickedButton5)
ON_BN_CLICKED(IDC_BUTTON6, &CMainBoardDlg::OnBnClickedButton6)
ON_BN_CLICKED(IDC_BUTTON_SEND, &CMainBoardDlg::OnBnClickedButtonSend)
END_MESSAGE_MAP()
// CMainBoardDlg 消息处理程序
LRESULT CMainBoardDlg::OnSwitchToMainBoardWnd(WPARAM wParam, LPARAM lParam)
{
//DoModal();
return 0;
}
BOOL CMainBoardDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CWCLaoDlg dlg;
INT_PTR iRet = dlg.DoModal();
if (iRet != IDOK)
{
EndDialog(1);
}
else
{
m_staticUserName.SetWindowText(UserInfo_GetUserName());
m_staticUserStatus.SetWindowText(UserInfo_GetUserStatusString(UserInfo_GetUserStatus()));
SetupFriendList();
ShowNotifyIcon();
}
// UserInfo_SetNetworkCallback(OnDropline);
return TRUE;
}
void CMainBoardDlg::ShowNotifyIcon()
{
m_nidNotifyIcon.cbSize = sizeof(NOTIFYICONDATA);
m_nidNotifyIcon.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_nidNotifyIcon.hWnd = m_hWnd;
lstrcpy(m_nidNotifyIcon.szTip, L"NotifyIcon Test");
m_nidNotifyIcon.uCallbackMessage = WM_NOTIFY_ICON;
m_nidNotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
Shell_NotifyIcon(NIM_ADD, &m_nidNotifyIcon);
}
BOOL CMainBoardDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN))
{
return NULL;
}
if (pMsg->message == WM_NCLBUTTONDOWN)
{
if (pMsg->hwnd == this->m_hWnd)
{
}
else
{
// ShowWindow(SW_SHOW);
}
}
return CDialog::PreTranslateMessage(pMsg);
}
void CMainBoardDlg::OnClose()
{
KillTimer(TIMER_breath);
MID_Logout();
MID_StopCommunication();
MID_Fini();
CDialog::OnClose();
}
void CMainBoardDlg::OnNMDblclkTreeFriendList(NMHDR *pNMHDR, LRESULT *pResult)
{
m_handleTreeItem = m_tvFriendList.GetSelectedItem();
g_sFriendKeyTemp = m_tvFriendList.GetItemText(m_tvFriendList.GetSelectedItem());
PrivateChatDlg *pcd = new PrivateChatDlg;
pcd->SetFriendKey(g_sFriendKeyTemp);
pcd->Create(IDD_DIALOG_PRIVATE_CHAT, this);
pcd->ShowWindow(SW_SHOW);
*pResult = 0;
}
void CMainBoardDlg::OnNMRClickTreeFriendList(NMHDR *pNMHDR, LRESULT *pResult)
{
// AfxMessageBox(m_tvFriendList.GetItemText(m_tvFriendList.GetSelectedItem()));
//show menu
//
m_menuFriend.LoadMenu(IDR_MENU_FRIEND);
CMenu *p = m_menuFriend.GetSubMenu(0);
CPoint point;
GetCursorPos(&point);
p->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_VERTICAL, point.x, point.y, this, TPM_LEFTALIGN);
m_menuFriend.DestroyMenu();
g_sFriendKeyTemp = m_tvFriendList.GetItemText(m_tvFriendList.GetSelectedItem());
*pResult = 0;
}
void CMainBoardDlg::SetupFriendList()
{
const struct_FriendInfo *p = UserInfo_GetFriendList();
//struct_FriendNode *m_friends = NULL, *pTemp = NULL;
//if (p)
//{
// pTemp = new struct_FriendNode;
// m_friends = p;
//}
while (p)
{
CString s(L"");
s.AppendFormat(L"%d", p->iUserID);
m_tvFriendList.InsertItem(s);
// HTREEITEM h = m_tvFriendList.InsertItem(0, s, 0, 0, 0, 0, p->iUserID, NULL,
NULL);
//pTemp->h = h;
//pTemp->iUserID = p->iUserID;
//pTemp->pNext = NULL;
//if (p)
//{
// pTemp->pNext = new struct_FriendNode;
// pTemp = pTemp->pNext;
//}
p = p->pNext;
}
}
void CMainBoardDlg::OnChat()
{
// AfxMessageBox(m_tvFriendList.GetItemText(m_handleTreeItem));
PrivateChatDlg *pcd = new PrivateChatDlg;
pcd->SetFriendKey(g_sFriendKeyTemp);
pcd->Create(IDD_DIALOG_PRIVATE_CHAT, this);
pcd->ShowWindow(SW_SHOW);
}
afx_msg void CMainBoardDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
if (nStatus == SC_MINIMIZE)
{
//ShowWindow(SW_HIDE);
//return;
}
}
void CMainBoardDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if (nID == SC_MINIMIZE)
{
//ShowWindow(SW_HIDE);
//return;
}
CDialog::OnSysCommand(nID, lParam);
}
afx_msg void CMainBoardDlg::OnSizing(UINT nType, int cx, int cy)
{
CMainBoardDlg::OnSize(nType, cx, cy);
//if (nType == SIZE_MINIMIZED)
//{
// ShowWindow(SW_HIDE);
// return;
//}
}
LRESULT CMainBoardDlg::OnNotifyIcon(WPARAM wParam,LPARAM IParam)
{
if ((IParam == WM_LBUTTONDOWN) || (IParam == WM_RBUTTONDOWN))
{
ModifyStyleEx(0,WS_EX_TOPMOST);
ShowWindow(SW_SHOW);
}
return 0;
}
void CMainBoardDlg::OnBnClickedButtonMinimize()
{
ShowWindow(SW_HIDE);
}
void CMainBoardDlg::OnNMClickTreeFriendList(NMHDR *pNMHDR, LRESULT *pResult)
{
m_handleTreeItem = m_tvFriendList.GetSelectedItem();
*pResult = 0;
}
void CMainBoardDlg::OnBnClickedButton2()
{ MID_OP_1();
}
void CMainBoardDlg::OnBnClickedButton3()
{ MID_OP_2();
}
void CMainBoardDlg::OnBnClickedButton4()
{ MID_OP_3();
}
void CMainBoardDlg::OnTimer(UINT nIDEvent)
{
static int i = 0;
if (i % 2 == 0)
{
MID_OP_1();
}
if (i % 3 == 0)
{
MID_OP_2();
}
if (i % 5 == 0)
{
MID_OP_3();
}
i++;
CDialog::OnTimer(nIDEvent);
}
void CMainBoardDlg::OnBnClickedButton5()
{
SetTimer(0, 4000, NULL);
}
void CMainBoardDlg::OnBnClickedButton6()
{
KillTimer(0);
}
void CMainBoardDlg::OnBnClickedButtonSend()
{
wchar_t s[1024] = {0};
m_editMessage.GetWindowTextW(s, 1024);
}
Original comment by Giggs...@gmail.com
on 29 Jul 2013 at 2:21
// PrivateChatDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "WCLao.h"
#include "PrivateChatDlg.h"
// PrivateChatDlg 对话框
IMPLEMENT_DYNAMIC(PrivateChatDlg, CDialog)
PrivateChatDlg::PrivateChatDlg(CWnd* pParent /*=NULL*/)
: CDialog(PrivateChatDlg::IDD, pParent)
{
}
PrivateChatDlg::~PrivateChatDlg()
{
}
void PrivateChatDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT_CHAT_LOG, m_editChatLog);
DDX_Control(pDX, IDC_EDIT_TO_SEND, m_editToSend);
DDX_Control(pDX, IDC_STATIC_FRIEND_NAME, m_staticFriendName);
DDX_Control(pDX, IDC_STATIC_MY_NAME, m_staticMyName);
DDX_Control(pDX, IDC_BUTTON_SEND, m_btnSend);
}
BOOL PrivateChatDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN))
{
return NULL;
}
return CDialog::PreTranslateMessage(pMsg);
}
void PrivateChatDlg::PostNcDestroy()
{
delete this;
}
BEGIN_MESSAGE_MAP(PrivateChatDlg, CDialog)
ON_BN_CLICKED(IDC_BUTTON_SEND, &PrivateChatDlg::OnBnClickedButtonSend)
END_MESSAGE_MAP()
// PrivateChatDlg 消息处理程序
BOOL PrivateChatDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetWindowText(m_sFriendKey);
return TRUE;
}
void PrivateChatDlg::SetFriendKey(CString sFriendKey)
{
m_sFriendKey = sFriendKey;
}
void PrivateChatDlg::OnBnClickedButtonSend()
{
//check void
//send text
//add test on above edit control
}
Original comment by Giggs...@gmail.com
on 29 Jul 2013 at 2:21
#pragma once
#include "../../Core/Common/WCLaoType.h"
typedef enum _enumSocketAvailableType
{
SOCKET_AVAILABLE_TYPE_READ = 0,
SOCKET_AVAILABLE_TYPE_WRITE,
SOCKET_AVAILABLE_TYPE_BOTH
}enumSocketAvailableType;
typedef enum _enumSocketAvailableError
{
SOCKET_AVAILABLE_TYPE_SUCCESS = 0,
SOCKET_AVAILABLE_TYPE_DROPLINE = -10000,
SOCKET_AVAILABLE_TYPE_OTHER = -10001,
SOCKET_AVAILABLE_TYPE_TIMEOUT = -10002
}enumSocketAvailableError;
typedef struct _struct_DataReceived
{
int offset;
int size;
char *pData;
}struct_DataReceived;
//interface
//
bool NW_Init(HWND h, int iProtocolHeaderSize, int iProtocolBodyLen,
CB_NetworkPackageCallback pCB);
void NW_Fini();
bool NW_PostConnect(char *pszServerIP, int iServerPort);
void NW_DisconnectToServer();
bool NW_PostSend(char *pszBuffer, int iLength);
int NW_SocketAvailable(SOCKET s, enumSocketAvailableType esat, unsigned int
iTimeoutSecond);
#include "stdafx.h"
#include "Net.h"
#include "../../Core/Debug/Debug.h"
#include "../../Core/Console/Console.h"
#include "../../Core/Common/String.h"
#include <winsock2.h>
#pragma comment(lib, "WS2_32")
#define TIMEOUT_Receive 500
#define TIMEOUT_Send 500
#define TIMEOUT_Connect 500
static SOCKET m_sockClient;
static struct_DataReceived *m_pDataReceived = NULL;
static DWORD WINAPI RecvThreadProc(LPVOID lpParam);
static HANDLE m_hRecvThread;
static CB_NetworkPackageCallback m_pCB = NULL;
static int m_iProtocolHeaderSize = 0;
static int m_iProtocolBodyLen = 0;
static bool StartSocket(BYTE byteMinorVersion, BYTE byteMajorVersion)
{
WSADATA wsaData;
WORD dwSockVersion = MAKEWORD(byteMinorVersion, byteMajorVersion);
if(::WSAStartup(dwSockVersion, &wsaData) != 0)
{
return false;
}
return true;
}
static void StopSocket()
{
::WSACleanup();
}
//pCB returns a package to upper layer
bool NW_Init(HWND h, int iProtocolHeaderSize, int iProtocolBodyLen,
CB_NetworkPackageCallback pCB)
{
m_iProtocolHeaderSize = iProtocolHeaderSize;
m_iProtocolBodyLen = iProtocolBodyLen;
m_pCB = pCB;
//start socket
if (!StartSocket(2, 2))
{
OutputDebugInfoW(L"加載Socket Dll 失敗!", __FILE__, __FUNCTION__);
return false;
}
m_pDataReceived = new struct_DataReceived;
memset(m_pDataReceived, 0, sizeof(struct_DataReceived));
m_pDataReceived->size = 2048;
m_pDataReceived->pData = new char[m_pDataReceived->size];
StartDebugConsole(h);
return true;
}
void NW_Fini()
{
StopSocket();
if (m_pDataReceived)
{
if (m_pDataReceived->pData)
{
delete m_pDataReceived->pData;
}
delete m_pDataReceived;
m_pDataReceived = NULL;
}
StopDebugConsole();
}
static DWORD WINAPI RecvThreadProc(LPVOID lpParam)
{
while (true)
{
int byteCount = 0;
//select
if ((byteCount = NW_SocketAvailable(m_sockClient, SOCKET_AVAILABLE_TYPE_READ, 20)) == SOCKET_AVAILABLE_TYPE_DROPLINE)
{
//check if disconnect by user.If yes....?
//...
PrintConsoleLog(WCLao_DEBUG, "drop line...");
break;
}
if (byteCount <= 0)
{
continue;
}
CStringA s = "";
s.Format("%d bytes can be Read", byteCount);
PrintConsoleLog(WCLao_DEBUG, s.GetBuffer());
//copy data from network
//
int byteCountActual = 0;
if (byteCount > m_pDataReceived->size - m_pDataReceived->offset)
{
//enlarge buffer
int newSize = m_pDataReceived->offset + byteCount;
char *buf = new char[newSize];
memcpy(buf, m_pDataReceived->pData, m_pDataReceived->offset);
delete m_pDataReceived->pData;
m_pDataReceived->pData = buf;
m_pDataReceived->size = newSize;
PrintConsoleLog(WCLao_DEBUG, "recv buf new size...");
}
byteCountActual = ::recv(m_sockClient, m_pDataReceived->pData + m_pDataReceived->offset, byteCount, 0);
m_pDataReceived->offset += byteCountActual;
//recv a full packet and post to UI thread
//
//check to see if it is at least a package length.If yes,remove to UI layer
do
{
int packageLen = 0;
if (m_pDataReceived->offset > m_iProtocolHeaderSize)
{
int *bodyLen = (int*)(m_pDataReceived->pData + m_iProtocolBodyLen);
packageLen = m_iProtocolHeaderSize + *bodyLen;
if (packageLen != 0 && m_pDataReceived->offset >= packageLen)
{
char *bufToUI = new char[packageLen];
memcpy(bufToUI, m_pDataReceived->pData, packageLen);
memcpy(m_pDataReceived->pData, m_pDataReceived->pData + packageLen, m_pDataReceived->offset - packageLen);
m_pDataReceived->offset = m_pDataReceived->offset - packageLen;
m_pCB(bufToUI, packageLen);
continue;
}
}
break;
}
while(true);
}
PrintConsoleLog(WCLao_DEBUG, "recv thread exit from while and exit...");
m_pCB(NULL, 0);
return 0;
}
bool NW_PostConnect(char *pszServerIP, int iServerPort)
{
//init client socket
m_sockClient = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(m_sockClient == INVALID_SOCKET)
{
OutputDebugInfoW(L"初始化Socket失敗", __FILE__, __FUNCTION__);
return false;
}
u_long ul = 1;
int iReturn = ::ioctlsocket(m_sockClient, FIONBIO, &ul);//none-blocking I/O
//connect
sockaddr_in siServerAddress;
siServerAddress.sin_family = AF_INET;
siServerAddress.sin_port = htons(iServerPort);
siServerAddress.sin_addr.S_un.S_addr = inet_addr(pszServerIP);
connect(m_sockClient, (SOCKADDR*)&siServerAddress, sizeof(sockaddr_in));
if (NW_SocketAvailable(m_sockClient, SOCKET_AVAILABLE_TYPE_WRITE, 10) <= 0)//can read == connect success
{
return false;
}
m_hRecvThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RecvThreadProc, NULL, 0, 0);
return true;
}
void NW_DisconnectToServer()
{
::closesocket(m_sockClient);
}
bool NW_PostSend(char *pszBuffer, int iLength)
{
if (NW_SocketAvailable(m_sockClient, SOCKET_AVAILABLE_TYPE_WRITE, 1) <= 0)
{
return false;
}
int iLengthSent = 0;
int count = 20;
int err = 0;
const int MAX_SEND_ONCE = 1024;
while (iLengthSent < iLength && count-- > 0)
{
if (SOCKET_ERROR == (err = ::send(m_sockClient, pszBuffer, (iLength - iLengthSent > MAX_SEND_ONCE ? MAX_SEND_ONCE : iLength - iLengthSent), 0)))
{
SAFE_DELETE(pszBuffer);
return false;
}
iLengthSent += err;
}
SAFE_DELETE(pszBuffer);
if (count == 0)
{
return false;
}
return true;
}
int NW_SocketAvailable(SOCKET socket, enumSocketAvailableType esat, unsigned
int iTimeoutSecond)
{
int ret = 0, readAble;
int errorcode;
//check the socket is writeable or not
FD_SET tbl;
struct timeval t;
SOCKET fd = (int)socket;
//check the availablity
if(fd <= 0)
{
return SOCKET_AVAILABLE_TYPE_OTHER;
}
t.tv_sec = iTimeoutSecond / 1000;
t.tv_usec = (iTimeoutSecond % 1000) * 1000;
FD_ZERO(&tbl);
FD_SET(fd, &tbl);
switch(esat)
{
case SOCKET_AVAILABLE_TYPE_WRITE:
ret = select(0, NULL, &tbl, NULL, &t);
break;
case SOCKET_AVAILABLE_TYPE_READ:
ret = select(0, &tbl, NULL, NULL, &t);
break;
case SOCKET_AVAILABLE_TYPE_BOTH:
ret = select(0, &tbl, &tbl, NULL, &t);
break;
default:
return SOCKET_AVAILABLE_TYPE_OTHER;
}
if(ret == -1)
{
if(WSAENOTSOCK == (errorcode = WSAGetLastError()))
{
return SOCKET_AVAILABLE_TYPE_DROPLINE;
}
return SOCKET_AVAILABLE_TYPE_OTHER;
}
else if(ret == 0)
{
return SOCKET_AVAILABLE_TYPE_TIMEOUT;
}
else
{
if(FD_ISSET(fd, &tbl) == 0)
{
return SOCKET_AVAILABLE_TYPE_TIMEOUT;
}
}
int size = sizeof(ret);
//get the available data
switch(esat)
{
case SOCKET_AVAILABLE_TYPE_WRITE:
getsockopt((int)socket, SOL_SOCKET, SO_SNDBUF, (char*)&ret, &size);
return ret;//return the available buffer for send
case SOCKET_AVAILABLE_TYPE_READ:
if(ioctlsocket((int)socket, FIONREAD, (u_long*)&readAble) < 0)
{
readAble = SOCKET_AVAILABLE_TYPE_OTHER;
}
if(readAble == 0 && ret > 0)
{
readAble = SOCKET_AVAILABLE_TYPE_DROPLINE;
}
return readAble;
case SOCKET_AVAILABLE_TYPE_BOTH:
if(ioctlsocket((int)socket, FIONREAD, (u_long*)&readAble) < 0)
{
readAble = SOCKET_AVAILABLE_TYPE_OTHER;
}
return readAble;
default:
return SOCKET_AVAILABLE_TYPE_OTHER;
}
}
Original comment by Giggs...@gmail.com
on 30 Jul 2013 at 10:49
Original issue reported on code.google.com by
Giggs...@gmail.com
on 17 Feb 2012 at 7:40