⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simplechatdlg.cpp

📁 这是一个简单的使用WinAPI基于WinSock的ICP/IP程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  return 0;
}

LRESULT CSimpleChatDlg::OnFileErrorReceive(WPARAM wParam, LPARAM)
{
  const CNotifErrorFile_Receive* pEvent = (const CNotifErrorFile_Receive*)wParam;
  const CNetFileTransmitInfo info = pEvent->getInfo();
  m_ctrlProgressReceived.SetPos(0);
  SetDlgItemText(IDST_PERCENTAGE_RECEIVED, "");
  SetDlgItemText(IDST_RECEIVED, "Failed.");
// disable cancel button
  GetDlgItem(IDBT_RECEIVE_CANCEL)->EnableWindow(FALSE);
  GetDlgItem(IDST_PERCENTAGE_RECEIVED)->ShowWindow(SW_HIDE);
  delete pEvent;
  return 0;
}

LRESULT CSimpleChatDlg::OnFileErrorSend(WPARAM wParam, LPARAM)
{
  const CNotifErrorFile_Send* pEvent = (const CNotifErrorFile_Send*)wParam;
  const CNetFileTransmitInfo info = pEvent->getInfo();
  m_ctrlProgressSent.SetPos(0);
  SetDlgItemText(IDST_PERCENTAGE_SENT, "");
  SetDlgItemText(IDST_SENT, "Failed.");
// enable the send button
  GetDlgItem(IDBT_SEND_FILE)->EnableWindow(TRUE);
// disable cancel button
  GetDlgItem(IDBT_SEND_CANCEL)->EnableWindow(FALSE);
  GetDlgItem(IDST_PERCENTAGE_SENT)->ShowWindow(SW_HIDE);
  delete pEvent;
  return 0;
}

LRESULT CSimpleChatDlg::OnFileAbortReceive(WPARAM wParam, LPARAM)
{
  const CNotifAbortFile_Receive* pEvent = (const CNotifAbortFile_Receive*)wParam;
  const CNetFileTransmitInfo info = pEvent->getInfo();
  m_ctrlProgressReceived.SetPos(0);
  SetDlgItemText(IDST_PERCENTAGE_RECEIVED, "");
  SetDlgItemText(IDST_RECEIVED, "Cancelled.");
// disable the cancel button
  GetDlgItem(IDBT_RECEIVE_CANCEL)->EnableWindow(FALSE);
  GetDlgItem(IDST_PERCENTAGE_RECEIVED)->ShowWindow(SW_HIDE);
  delete pEvent;
  return 0;
}

LRESULT CSimpleChatDlg::OnFileAbortSend(WPARAM wParam, LPARAM)
{
  const CNotifAbortFile_Send* pEvent = (const CNotifAbortFile_Send*)wParam;
  const CNetFileTransmitInfo info = pEvent->getInfo();
  m_ctrlProgressSent.SetPos(0);
  SetDlgItemText(IDST_PERCENTAGE_SENT, "");
  SetDlgItemText(IDST_SENT, "Cancelled.");
// enable the send button
  GetDlgItem(IDBT_SEND_FILE)->EnableWindow(TRUE);
// disable cancel button
  GetDlgItem(IDBT_SEND_CANCEL)->EnableWindow(FALSE);
  GetDlgItem(IDST_PERCENTAGE_SENT)->ShowWindow(SW_HIDE);
  delete pEvent;
  return 0;
}
void CSimpleChatDlg::Listen(string& addr)
{
// cleanup
  DisconnectAll();
// prepare the thread for accepting
  if (!m_acceptorThread.SetAddress(addr)) {
   	MessageBox("Failed to listen on the given address and port. Please correct your parameters.", "Simple Chat", MB_ICONINFORMATION|MB_OK);
	return;
  }
// subscribe fro the notification from the thread
  m_acceptorThread.Subscribe(this);
// start accepting (none blocking, so the thread can successfuly terminate 
// if application exists while thread is accepting) 
  m_acceptorThread.Start();

  GetDlgItem(IDBT_GO)->EnableWindow(FALSE);
// enable the disconnect button
  GetDlgItem(IDBT_DISCONNECT)->EnableWindow(TRUE);

// minimize the window and create the tray
  SetupTrayIcon(true);
}

LRESULT CSimpleChatDlg::OnListening(WPARAM wParam, LPARAM)
{
  const CNotifListening* pEvent = (const CNotifListening*)wParam;
  delete pEvent;

  if (m_acceptorThread.IsStoped()) return 0;

  CTimeSpan span =  CTime::GetCurrentTime() - m_time;
  if (span.GetSeconds() < 1) return 0;
  m_time = CTime::GetCurrentTime();

  int nDots = m_strStatus.GetLength() - strlen("Listening ");
  m_strStatus = "Listening ";
  if (nDots > 30) nDots = 0;
  for (int i=0; i<nDots + 1; i++)
	m_strStatus += '>';

  GetDlgItem(IDST_CONNECT_STATUS)->SetWindowText(m_strStatus);
  return 0;
}

LRESULT CSimpleChatDlg::OnAcceptError(WPARAM wParam, LPARAM)
{
  delete (CNotifEvent*)wParam;
// restore the window
  ShowWindow(SW_RESTORE);

  MessageBox("A remote peer has arrived but failed to establish a connection on the given address and port. Please try to change the port number.", "Simple Chat", MB_ICONINFORMATION|MB_OK);
// stop the thread 
  m_acceptorThread.Stop();
// restore the window and remove the tray
  SetupTrayIcon(false);
  return 0;
}

LRESULT CSimpleChatDlg::OnAccept(WPARAM wParam, LPARAM)
{
  delete (CNotifEvent*)wParam;

// by now the acceptor execution thread is no longer running (accepting)
// however the object exists for the lifetime of this dialog

  CNetConnection* pConnector = m_acceptorThread.GetConnection();

  if (!pConnector) {
	WriteSystem("a Peer's attempt to connect has failed");
	return 0;
  }

// got the connection to the peer. Attach in to the stream
  m_NetStream.Attach(pConnector);

// stop the thread 
  m_acceptorThread.Stop();

// reset the progress status
  m_strStatus.Empty();
  GetDlgItem(IDST_CONNECT_STATUS)->SetWindowText(m_strStatus);

  DisableControls();

// restore the window and remove the tray
  SetupTrayIcon(false);

// start up the file listener thread
  ListenForFiles();

  return 0;
}

void CSimpleChatDlg::DisconnectAll() 
{
// if the acceptor thread is running, stop it
  if (!m_acceptorThread.IsStoped()) {
// restore the window and remove the tray
    SetupTrayIcon(false);
// stop thread
	m_acceptorThread.Stop();
// reset the progress status
	m_strStatus.Empty();
	UpdateData(FALSE);
  }
// if the file acceptor thread is running, stop it
  m_acceptorFileThread.Stop();

// stop listening for incoming data
//  KillTimer(m_nCheckForData);

  EnableControls();

// close the text message channel
  CNetConnection* pConnection = m_NetStream.Detach();
  if (!pConnection) return;
// break the pipe
  pConnection->Disconnect();
  delete pConnection;

  DisconnectFileTransfers();

}

void CSimpleChatDlg::DisconnectFileTransfers()
{
// abort any file transfers
  CThreadStorage& storage = g_getThreadStorage();
  while (storage.Size() > 0) {
	CNetThread* pThread = storage.GetAt(storage.Size() - 1);
// block until thread quits, selfremoves from the storage and selfdestructs
	if (pThread)
	  pThread->Stop();
  }
  
// empty the queue from the notifications
  while (IsThereEvent()) {
	CNotifEvent* pEvent = GetEvent();
	SendMessage(pEvent->event_id(), (WPARAM)pEvent);
  }
}

bool CSimpleChatDlg::SendText() 
{
  if (!m_NetStream.IsOpen()) {
	WriteSystem("The connection is broken.");
    return false;
  }

  UpdateData();

  CNetText* pNetText = 0;
  try {
// create new message with local host id, remote host id and the text message  
    CNetText::MSG msg;
    msg.m_strText = m_strText;
    pNetText = new CNetText(m_NetStream.GetConnection()->GetRemoteHandle(), m_NetStream.GetConnection()->GetLocalHandle(), msg) ;
// send the message
	m_NetStream << *pNetText;
	WriteYourName();
// display this message on the local screen
    WriteMsg(pNetText->GetText());
// clean up the edit box
    OnClear();
    GetDlgItem(IDED_TEXT)->SetFocus();
  } catch (CNetException e) {
// if cannot send notify the user and do not clean up the edit box
	WriteSystem("The message cannot be delivered.");
// the connection is broken, close the socket
	DisconnectAll();
	delete pNetText;
	return false;
  }
// clean up
  delete pNetText;
  return true;
}

bool CSimpleChatDlg::SendLocalFileAcceptAddr()
{
  if (!m_NetStream.IsOpen()) {
	WriteSystem("The connection is broken.");
    return false;
  }

  CNetStatus status;
  status.SetCode(nsAcceptAddr);
  status.SetText(m_acceptorFileThread.GetAddress());
  try {
// send the message
	m_NetStream << status;
  } catch (CNetException e) {
// if cannot send notify the user and do not clean up the edit box
	WriteSystem("The message cannot be delivered.");
// the connection is broken, close the socket
	DisconnectAll();
	return false;
  }
  return true;
}

bool CSimpleChatDlg::SendFile()
{
  if (!m_NetStream.IsOpen()) {
	WriteSystem("The connection is broken.");
    return false;
  }

  CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, "All Files (*.*)|*.*||", this);

  if (dlg.DoModal() == IDCANCEL)
	return true;
  
  CString strPath = dlg.GetPathName();
// form the connect string
  CString strConnect = "file = '";
  strConnect += strPath;
  strConnect += "'; openopt = 'read'";

// create the provider address
  CNetFileAddress addr;
  addr.SetConnectString(strConnect);
// create the provider's connector
  CNetBinFileConnector* pConnector = new CNetBinFileConnector;
// connect!
  pConnector->Connect(addr);

// create the file header
  strPath.Delete(strPath.Find(dlg.GetFileName()), dlg.GetFileName().GetLength());
  CNetFileHdr  hdr;
  hdr.SetDirectory(false);
  hdr.SetProviderPath(strPath);
  hdr.SetProviderName(dlg.GetFileName());
  hdr.SetFileSize(pConnector->GetSize());
// create the sending thread
  CSenderThread* pThread = new CSenderThread(hdr);
// set the provider's connector
  pThread->SetProviderConnector(pConnector);
// set the consumer's address
  pThread->SetConsumerAddress(GetRemoteFileAcceptorAddr());
// subscribe for notifications
  pThread->Subscribe(this);
// add the thread to the thread storage
  g_getThreadStorage().Add(pThread);
// run it!
  pThread->Start();

// save the thread's id these buttons control
  CWnd* pSend = GetDlgItem(IDST_SEND);
  pSend->SetWindowContextHelpId(pThread->GetThreadId());
// disable the button
  GetDlgItem(IDBT_SEND_FILE)->EnableWindow(FALSE);
// enable cancel button
  GetDlgItem(IDBT_SEND_CANCEL)->EnableWindow(TRUE);
  GetDlgItem(IDST_PERCENTAGE_SENT)->ShowWindow(SW_SHOW);
  GetDlgItem(IDST_PERCENTAGE_SENT)->UpdateWindow();
/*
  if (!m_file.Open(strPath, CFile::modeRead)) {
	MessageBox("Cannot open the file", "Error", MB_OK|MB_ICONERROR);
	return false;
  }
// set the file length;
  m_nFLen = m_file.GetLength();

// create the message
  CNetList list;
  list.SetDataRequestCallback(this, DataRequest);
    
// set the max number of packets
  DWORD nLen  = (m_nFLen > MAX_NET_PACKET) ? m_nFLen : MAX_NET_PACKET;
  short nTail = (nLen % MAX_NET_PACKET > 0) ? 1 : 0;
  list.SetMaxElem(nLen / MAX_NET_PACKET + nTail);
// send it!
  m_NetStream << list;
*/
  return true;
}
/*
bool CSimpleChatDlg::DataRequest(void* pCaller, CNetList* pList)
{
  CSimpleChatDlg* pThis = (CSimpleChatDlg*)pCaller;

  DWORD nPos = pThis->m_file.GetPosition();

// end of the file
  if (pThis->m_nFLen == nPos) {
	pThis->m_file.Close();
	return true;
  }

// figure out how many bytes to read
  DWORD nSz = (pThis->m_nFLen - nPos > MAX_NET_PACKET) ? MAX_NET_PACKET : pThis->m_nFLen - nPos;

  char szBuff[MAX_NET_PACKET];
  DWORD nRead = 0;
// if read less, that's a problem
  if ((nRead = pThis->m_file.Read(szBuff, nSz)) != nSz) {
	pThis->m_file.Close();
	return false;
  }

  CNetPacket* pMsg = new CNetPacket;
  pMsg->SetData(szBuff, nSz, pList->GetElemN() + 1);
// send the message
  pList->AddElem(pMsg);

  if (nPos + nRead == pThis->m_nFLen)
    pThis->m_file.Close();
  return true;
}
*/
bool CSimpleChatDlg::SendLogin(netStatus ns)
{
  if (!m_NetStream.IsOpen()) {
	WriteSystem("The connection is broken.");
    return false;
  }

  UpdateData();

// create new message with the local user name and the text welcome message  
  CNetLogin login;
  login.SetCode(ns);
  login.SetName(m_strYou);
  if (m_bUseMsg) 
    login.SetText(m_strWelMsg);
  try {
// send the message
	m_NetStream << login;
  } catch (CNetException e) {
// if cannot send notify the user and do not clean up the edit box
	WriteSystem("The message cannot be delivered.");
// the connection is broken, close the socket
	DisconnectAll();
	return false;
  }
  if (ns == nsLogin)
    WriteSystem("You have joined the chat room.");
  else 
    if (ns == nsNickChange)
  	  WriteSystem("You have changed your nick name.");
// don't show the welcome message if it's empty
  if (m_bUseMsg && !m_strWelMsg.IsEmpty()) {
    WriteYourName();
// display this message on the local screen
    WriteMsg(login.GetText());
  }
// clean up the edit box
  OnClear();
  GetDlgItem(IDED_TEXT)->SetFocus();
  return true;
}

bool CSimpleChatDlg::SendLogout()
{
  if (!m_NetStream.IsOpen()) {
	WriteSystem("The connection is broken.");
    return false;
  }

  UpdateData();

// create the logout message
  CNetStatus logout;
  logout.SetCode(nsLogout);
  if (m_bUseMsg) 
    logout.SetText(m_strByeMsg);

  try {
// send the message
	m_NetStream << logout;
  } catch (CNetException e) {
// if cannot send notify the user and do not clean up the edit box
	WriteSystem("The message cannot be delivered.");
// the connection is broken, close the socket
	DisconnectAll();
	return false;
  }
  WriteSystem("You have left the chat room.");
  if (m_bUseMsg && !m_strByeMsg.IsEmpty()) {
    WriteYourName();
// display this message on the local screen
    WriteMsg(logout.GetText());
  }
// clean up the edit box
  OnClear();
  GetDlgItem(IDED_TEXT)->SetFocus();
  return true;
}

bool CSimpleChatDlg::SendLocalUserActivityStatus(CNetStatus& status)
{
  if (!m_NetStream.IsOpen())
    return false;

// send the local user activity status to the remote peer
  try {
    m_NetStream << status;
  } catch (CNetException e) {
// the connection is broken, close the socket(s)
	DisconnectAll();
	return false;
  }
  return true;
}

void CSimpleChatDlg::Receive() 
{
  CNetMsg*			pMsg = 0;
// read it
  try {
    m_NetStream >> pMsg;
// deal with the message based on its type
	m_msgConverter.SetMsg(pMsg);
	m_msgConverter.Process();
  } catch (CNetException e) {
// if cannot extract notify the user
	WriteSystem("The message was received but cannot be read.");
// the connection is broken, close the socket
	DisconnectAll();
  }
// clean up
  delete pMsg;
}

void CSimpleChatDlg::OnSend() 
{
  SendText();
}

void CSimpleChatDlg::OnSendFile() 
{
  SendFile();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -