?? secretchatdlg.cpp
字號:
dwRead += dw;
}
SetFileTime((HANDLE)destFile.m_hFile,&StreamFileInfo.ftCreationTime,
&StreamFileInfo.ftLastAccessTime,&StreamFileInfo.ftLastWriteTime);
destFile.Close();
SetFileAttributes(StreamFileInfo.szFileTitle,StreamFileInfo.dwFileAttributes);
sockClient.Close();
//詢問打開文件,還是用遞送消息吧,反正沒事
if(pMain->m_send_file)//m_send_file是中止標志
pMain->PostMessage( WM_RUNHIDE,1,0);
//恢復現場
pMain->send_file_comeback_scene();
//AfxMessageBox("接收完畢!");
return 0;
}
/*
DWORD WINAPI send_file_thread(LPVOID param) //發送文件線程
{
CSecretChatDlg * pMain = (CSecretChatDlg *)param;
MessagePackage msg;
msg.head = HEAD_SENDFILE;
msg.ID = HEAD_SENDFILE_TEXT;
msg.n = SENDFILESIZE;
//::Sleep(100); //發送的太快就會出錯
//把消息包分成若干塊大小為SENDFILESIZE
CFile file;
if(!file.Open(
pMain->m_send_file_name,
CFile::modeRead | CFile::typeBinary))
{
AfxMessageBox("發送的文件無法讀取");
return 0;
}
file.Seek(pMain->m_send_file_seek_position, CFile::begin);
file.Read(msg.data, SENDFILESIZE);//返回的是現在讀寫文件的位置
pMain->m_send_file_seek_position += SENDFILESIZE;
pMain->SendData(msg, SENDFILESIZE + 12/消息包頭部長度/);
file.Close();
return 0;
}
DWORD WINAPI receive_file_thread(LPVOID param) //接收文件線程
{
CSecretChatDlg * pMain = (CSecretChatDlg *)param;
MessagePackage msg;
msg = pMain->m_receive_file_buffer;
CFile file;
if(!file.Open(
pMain->m_receive_file_name,
CFile::modeWrite | CFile::typeBinary))
{
AfxMessageBox("發送的文件無法讀取");
return 0;
}
file.SeekToEnd(); //每次從尾部寫入
file.Write(msg.data, msg.n);
pMain->m_send_file_seek_position += msg.n; //已經接收文件的大小
if(file.GetLength() >= (unsigned int)pMain->m_send_file_length)
{ //這就表示接收完了文件
file.SetLength(pMain->m_send_file_length);
file.Close();
//提示成功接收
msg.head = HEAD_SENDFILE;
msg.ID = HEAD_SENDFILE_SUCCEED;
pMain->SendData(msg, 12);
//恢復現場
pMain->send_file_comeback_scene();
//詢問打開文件,還是用遞送消息吧,反正沒事
pMain->PostMessage( WM_RUNHIDE,1,0);
}
else
{
file.Close();
//收到一個塊后,就向對方確認之后再接收
msg.head = HEAD_SENDFILE;
msg.ID = HEAD_SENDFILE_CONCENT;
pMain->SendData(msg, 12);
}
return 0;
}*/
///////////////////////////////////
//在任務欄狀態區添加圖標
BOOL MyTaskBarAddIcon(HWND hwnd,UINT uID,HICON hicon,LPSTR lpszTip)
{
BOOL res;
NOTIFYICONDATA tnid;
tnid.cbSize = sizeof(NOTIFYICONDATA);
tnid.hWnd = hwnd;
tnid.uID = uID;
tnid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
tnid.uCallbackMessage = MYWM_NOTIFYICON;
tnid.hIcon = hicon;
if (lpszTip) lstrcpyn(tnid.szTip, lpszTip, sizeof(tnid.szTip));
else tnid.szTip[0] = '\0';
res = Shell_NotifyIcon(NIM_ADD,&tnid);
if (hicon) DestroyIcon(hicon);
return res;
}
//從任務欄狀態區刪除圖標
BOOL MyTaskBarDeleteIcon( UINT uID,HWND hwnd)
{
BOOL res;
NOTIFYICONDATA tnid;
tnid.cbSize = sizeof(NOTIFYICONDATA);
tnid.hWnd = hwnd;
tnid.uID = uID;
res = Shell_NotifyIcon(NIM_DELETE, &tnid);
return res;
}
/////////////////
//托盤圖標事件
void CSecretChatDlg::OnMyIconNotify(WPARAM wParam/*uID*/,LPARAM lParam/*消息標識值*/)
{
switch( lParam)
{
case WM_LBUTTONDOWN: //點擊圖標
if (IsWindowVisible()) //如果窗口已打開,隱藏窗口
{
//利用這兩個動作就可實現動畫了
ShowWindow( SW_MINIMIZE);
ShowWindow(SW_HIDE); //隱藏動畫
}
else //否則,顯示窗口
{
//利用這兩個動作就可實現動畫了
ShowWindow( SW_MINIMIZE);
ShowWindow( SW_SHOWNORMAL); //顯示動畫
}
break;
case WM_RBUTTONDOWN: //右擊圖標
//右擊是為了彈出菜單
//要彈出菜單主菜單的屬性必須要取消view as popup屬性
CPoint point;
GetCursorPos( &point);
CMenu menu;
VERIFY( menu.LoadMenu( IDR_ICONMENU));
CMenu * pMenu = menu.GetSubMenu(0);
if(AfxGetApp()->GetProfileInt("General", "Top", 0))
{ //總在前面標記
pMenu->CheckMenuItem( ID_TOP,MF_CHECKED | MF_BYCOMMAND);
}
//要顯示窗口還是隱藏
if( IsWindowVisible())
{
pMenu->DeleteMenu( ID_SHOW,MF_BYCOMMAND);
}
else
{
pMenu->DeleteMenu( ID_HIDE,MF_BYCOMMAND);
}
pMenu->TrackPopupMenu( 32,point.x,point.y,this);
break;
}
}
BOOL CSecretChatDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//沒有聯機
m_online = FALSE;
//窗口初始化顯示和設置函數
InitializationWindow();
/*創建套接字,并在套接字上監聽連接*/
m_socketListen.Create(LISTEN_PORT);
m_bListen = m_socketListen.Listen(); //返回值可以判斷是否監聽成功,否則就已有實例在監聽
//關閉服務器和客戶機的套接字對象
m_pSocket = NULL;
m_socketListen.m_pServiceSocket = NULL;
//每隔30秒就向另一方發在線通知,還是不要這個在線通知了這樣會減少一些錯誤吧
SetTimer(1003, 30000, NULL);
//初始化CRITICAL_SECTION變量(m_cs.LockCount會等于-1)?不一定
::InitializeCriticalSection(&m_cs_receive);
//可以發送文件
m_send_file = FALSE;
//測試部分
return TRUE; // return TRUE unless you set the focus to a control
}
void CSecretChatDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
//CAboutDlg dlgAbout;
//dlgAbout.DoModal();
m_setupDlg.m_index = 4;
m_setupDlg.DoModal();
}
else if(nID == IDS_JIAMI)
{
HKEY hkey;
char sz[MAX_PATH]; //緩沖區必須要和設置時的相同才能讀到數據
DWORD dwtype, sl = MAX_PATH;
::RegOpenKeyEx(
HKEY_CURRENT_USER,
"Software\\文件密使\\Application",
NULL,
KEY_ALL_ACCESS,
&hkey);
::RegQueryValueEx(
hkey,
"DirectoryName",
NULL,
&dwtype,
(LPBYTE)sz,
&sl);
::RegCloseKey(hkey);
CString strJiaMi = sz;
::ShellExecute(
NULL,
"open",
strJiaMi + "\\jiami.exe",
"",
"",
SW_SHOW);
}
else if(nID == IDS_HELP)
{
::ShellExecute(
m_hWnd,
"open",
"http://www.wjmshome.com/SecretChat.htm",
"",
"",
SW_SHOWNORMAL);
}
else if(nID == SC_MINIMIZE)
{
//利用這兩個動作就可實現動畫了
if(AfxGetApp()->GetProfileInt("General", "Tray", 1))
{
ShowWindow( SW_MINIMIZE);
ShowWindow(SW_HIDE); //隱藏動畫
}
else
{
ShowWindow( SW_MINIMIZE);
}
}
CDialog::OnSysCommand(nID, lParam);
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CSecretChatDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
HCURSOR CSecretChatDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CSecretChatDlg::OnTimer(UINT nIDEvent)
{
if(nIDEvent == 1001) //只負責清除狀態提示欄的信息
{
m_statusMessages.SetWindowText("");
}
//LAN啟動周期性連接
else if(nIDEvent == 1002)
{
if(m_online)
return;
//只有在沒有連接的情況下才,進行LAN周期性連接
m_IP = AfxGetApp()->GetProfileString("General", "LANIP");
m_port = LISTEN_PORT;
if(!prevent_connect())
return; //防止自己連接自己
m_statusMessages.SetWindowText("連接中...");
/*連接不能在線程了完成否則對方無法創建得到服務器套接字對象,
所以就發不了消息給客戶機了*/
if( (NULL != (m_pSocket = new CClientSocket)) //確定了指向那個套接字
&& m_pSocket->Create() ) //創建套接字對象
{
if(m_pSocket->Connect(m_IP, m_port) )
{
m_clientOrService = FALSE; //客戶端
connect_succeed_update();
}
else
{
CloseSocket();//關閉套接字
}
}
/*非主線程進入得地址不能訪問套接字對象
unsigned long nThreadID;
::CreateThread(
NULL,
0,
connect_thread,
this,
0,
&nThreadID);*/
}
/************每隔30秒就向另一方發在線通知**********/
else if(nIDEvent == 1003)
{
if(m_online)
{
//每隔30秒向對方發送一次在線通知
MessagePackage msg;
msg.head = HEAD_ZAIXIANBIAOJI;
SendData(msg, 12);
//當連續有6個30秒沒收到對方的在線通知就斷定對方不在斷開了
m_zai_xian_biao_ji++; //在線標記計算器加一
if(m_zai_xian_biao_ji > 6)
{
if(!m_send_file) //發送文件時不要斷開,因為可能由于發送文件使得消息無法發送出去,而產生了錯誤
{
Disconnection();
m_statusMessages.SetWindowText("對方意外的斷開了連接!"); //已經斷開服務器連接
}
}
}
/*unsigned long nThreadID;
::CreateThread(
NULL,
0,
zai_xian_biao_ji_thread,
this,
0,
&nThreadID);*/
}
CDialog::OnTimer(nIDEvent);
}
void CSecretChatDlg::OnOK()
{
// TODO: Add extra validation here
//CDialog::OnOK();
}
void CSecretChatDlg::OnCancel()
{
//文件傳送問答
if(m_send_file)
{
if(MessageBox(
"是否要取消文件傳送?",
"密聊",
MB_YESNO | MB_ICONQUESTION) == IDYES)
{
//::TerminateThread(
// m_send_file_thread_handle,
// NO_ERROR); //結束線程
MessagePackage msg;
msg.head = HEAD_SENDFILE;
msg.ID = HEAD_SENDFILE_STOP;
SendData(msg, 12);
//恢復現場
send_file_comeback_scene();
}
return;
}
if(m_online) //聯機時或文件傳送中的處理,要用戶斷開連接才能斷開
{
if(MessageBox(
"連接中,是否關閉?",
"密聊",
MB_YESNO | MB_ICONQUESTION) == IDNO)
{
return;
}
//只是告訴對方我已經關閉密聊
MessagePackage msg;
msg.head = HEAD_DISCONNECTION;
msg.ID = HEAD_DISCONNECTION_CLOSE;
SendData(msg, 12);
Disconnection();
}
//清除
MyTaskBarDeleteIcon(101, m_hWnd); //從任務欄狀態區刪除圖標
//保存窗口位置
if(IsWindowVisible() && !IsIconic())
{ //要可見,沒最小化
CRect rect;
GetWindowRect(rect); //保存窗口位置
CString str;
str.Format("%i,%i,%i,%i",
rect.top,
rect.bottom,
rect.left,
rect.right);
AfxGetApp()->WriteProfileString("Window", "Position", str);
}
CDialog::OnCancel();
}
void CSecretChatDlg::OnConnectDisconnection() //連接和斷開
{
//文件傳送問答
if(m_send_file)
{
if(MessageBox(
"是否要取消文件傳送?",
"密聊",
MB_YESNO | MB_ICONQUESTION) == IDYES)
{
//::TerminateThread(
// m_send_file_thread_handle,
// NO_ERROR); //結束線程
MessagePackage msg;
msg.head = HEAD_SENDFILE;
msg.ID = HEAD_SENDFILE_STOP;
SendData(msg, 12);
//恢復現場
send_file_comeback_scene();
}
return;
}
if(m_online) //聯機時的處理
{
if( MessageBox(
"是否要斷開連接?",
"密聊",
MB_YESNO | MB_ICONQUESTION) == IDNO)
{
return;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -