📄 secretchatdlg.cpp
字号:
AfxGetResourceHandle(),
hRsrc);
::sndPlaySound(
(LPCTSTR)::LockResource(hglb),
SND_MEMORY | SND_SYNC | SND_NODEFAULT);
::FreeResource(hglb);
/**********************************/
}
BOOL CSecretChatDlg::Disconnection() //断开连接
{
if(!m_online) //联机时的处理
return TRUE;
/*正在发送或接收消息时不能断开连接,否则会出现严重的错误提示
if(m_send != 0 || m_receive != -1)
{
MessageBox(
"发送或接收消息时,请别断开连接",
"密聊",
MB_ICONEXCLAMATION);
return FALSE;
}*/
m_statusMessages.SetWindowText("已经断开连接"); //已经断开服务器连接
//断开连接成功后改变按钮的状态
CString str = "连接";
m_connect.SetIcon(IDI_CONNECT);
m_connect.SetTooltipText(&str);
m_connect.SetWindowText(str);
/*这里有些逻辑错误,双方会造成循环发送HEAD_DISCONNECTION消息
MessagePackage msg;
msg.head = HEAD_DISCONNECTION;
SendData(msg, 12);
*/
m_online = FALSE; //提示断线
TrayIcon(); //设置状态区图标
SetWindowText("密聊 (未连接)"); //提示已连接还是未连接
//关闭套接字
CloseSocket();//断开了那还怎么发通知断线消息给对方呀?
PlayWaveSound(IDR_OFFLINE); //断开时的声音提示
return TRUE;
}
BOOL CSecretChatDlg::Connect() //建立连接
{
if(m_online) //没联机时的处理
return TRUE;
if(m_connectDlg.DoModal() != IDOK)
{
return FALSE;
}
m_IP = m_connectDlg.m_IP;
m_port = m_connectDlg.m_port;
if(!prevent_connect())
return FALSE; //防止自己连接自己
m_statusMessages.SetWindowText("连接中...");
/*连接不能在线程了完成否则对方无法创建得到服务器套接字对象,
所以就发不了消息给客户机了*/
if( (NULL != (m_pSocket = new CClientSocket)) //确定了指向那个套接字
&& m_pSocket->Create() ) //创建套接字对象
{
if(m_pSocket->Connect(m_IP, m_port) )
{
//成功连接的IP地址记入注册表中
AfxGetApp()->WriteProfileString("Connect", "IPHistory", m_IP);
m_clientOrService = FALSE; //客户端
connect_succeed_update();
}
else
{
CloseSocket();//关闭套接字
m_statusMessages.SetWindowText("连接失败!");
PlayWaveSound(IDR_OFFLINE); //连接失败时的声音提示
return FALSE;
}
}
else
{
return FALSE;
}
/*
unsigned long nThreadID;
::CreateThread(
NULL,
0,
connect_thread,
this,
0,
&nThreadID);*/
return TRUE;
}
int CSecretChatDlg::SendData(MessagePackage &msg, int n) //发送数据
{
//断开连接就不能再发送消息了
if(!m_online)
return 0;
if(m_clientOrService) //服务器端
{
m_socketListen.m_pServiceSocket->Send(&msg, n);
//错误提示
CuoWuTiShi();
}
else //客户机端
{
m_pSocket->Send(&msg, n);
//错误提示
CuoWuTiShi();
}
return 0;
}
void CSecretChatDlg::WinHelp(DWORD dwData, UINT nCmd) //按下F1打开帮助文件
{
::ShellExecute(
m_hWnd,
"open",
"http://www.wjmshome.com/SecretChat.htm",
"",
"",
SW_SHOWNORMAL);
//CDialog::WinHelp(dwData, nCmd);
}
void CSecretChatDlg::OnSecretkey() //通讯双方的密钥设置和密钥管理
{
m_setupDlg.m_index = 0;
if(m_setupDlg.DoModal() == IDOK)
{
}
}
void CSecretChatDlg::OnSetup() //常规设置
{
m_setupDlg.m_index = 3;
if(m_setupDlg.DoModal() == IDOK)
{
}
}
BOOL CSecretChatDlg::InstallPrivateKey(CString fileName/*安装的文件名*/)
{
if(fileName == "")
{ //当没说明安装的文件时,就安装默认的
fileName =
m_appName
+ "\\user\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey");
}
CFile file;
SecretKey secretKey;
if(!file.Open(
fileName,
CFile::modeReadWrite | CFile::typeBinary))
return FALSE;
if(file.GetLength() != sizeof(SecretKey))
return FALSE;
file.SeekToBegin();
file.Read(&secretKey, sizeof(SecretKey));
file.Close();
if(secretKey.ID != SECRETKEY_ID)
return FALSE;
if(secretKey.privateOrPublic != SECRETKEY_PRIVATE)
return FALSE;
m_userNameStatic.SetWindowText(AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey"));
m_userNameStatic.SetLink(TRUE,FALSE);
m_userNameStatic.SetTextColor(RGB(0,128,192));
m_userNameStatic.SetLinkCursor(AfxGetApp()->LoadCursor( IDC_HAND));
m_private_key_send.SK_to_vlong(secretKey.sk/*自己的私钥*/);
m_private_key_receive.SK_to_vlong(secretKey.sk/*自己的私钥*/);
return TRUE;
}
BOOL CSecretChatDlg::InstallPublicKey(CString fileName/*安装的文件名*/)
{
if(fileName == "")
{ //当没说明安装的文件时,就安装默认的
fileName =
m_appName
+ "\\friend\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey");
}
CFile file;
SecretKey secretKey;
if(!file.Open(
fileName,
CFile::modeReadWrite | CFile::typeBinary))
return FALSE;
if(file.GetLength() != sizeof(SecretKey))
return FALSE;
file.SeekToBegin();
file.Read(&secretKey, sizeof(SecretKey));
file.Close();
if(secretKey.ID != SECRETKEY_ID)
return FALSE;
if(secretKey.privateOrPublic != SECRETKEY_PUBLIC)
return FALSE;
m_friendNameStatic.SetWindowText(AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey"));
m_friendNameStatic.SetLink(TRUE,FALSE);
m_friendNameStatic.SetTextColor(RGB(255,128,128));
m_friendNameStatic.SetLinkCursor(AfxGetApp()->LoadCursor( IDC_HAND));
m_public_key_send.PK_to_vlong(secretKey.pk/*对方的公钥*/);
m_public_key_receive.PK_to_vlong(secretKey.pk/*对方的公钥*/);
return TRUE;
}
BOOL CSecretChatDlg::MyUpdateData() //根据注册表数据进行设置
{
//显示出私钥和公钥名
m_userNameStatic.SetWindowText(
AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey"));
m_friendNameStatic.SetWindowText(
AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey"));
m_userNameStatic.SetLink(TRUE,FALSE);
m_userNameStatic.SetTextColor(RGB(0,128,192));
m_userNameStatic.SetLinkCursor(AfxGetApp()->LoadCursor( IDC_HAND));
m_friendNameStatic.SetLink(TRUE,FALSE);
m_friendNameStatic.SetTextColor(RGB(255,128,128));
m_friendNameStatic.SetLinkCursor(AfxGetApp()->LoadCursor( IDC_HAND));
//顶层窗口
if(AfxGetApp()->GetProfileInt("General", "Top", 0))
{
::SetWindowPos(
GetSafeHwnd(),
HWND_TOPMOST,
0,0,0,0,
SWP_NOMOVE | SWP_NOSIZE);
}
else
{
::SetWindowPos(
GetSafeHwnd(),
HWND_NOTOPMOST,
0,0,0,0,
SWP_NOMOVE | SWP_NOSIZE);
}
//显示位置
TrayIcon();
//LAN启动周期性连接
if(AfxGetApp()->GetProfileInt("General", "LANStartup", 0))
{
SetTimer(1002, 60000, NULL); //以60秒为周期连接LAN
}
else
{
KillTimer(1002);
}
//安装私钥和公钥
InstallPrivateKey();
InstallPublicKey();
return TRUE;
}
BOOL CSecretChatDlg::PreTranslateMessage(MSG* pMsg)
{
//快捷键
if( pMsg->message == WM_KEYDOWN)
{
BOOL bCtrl = ::GetKeyState( VK_CONTROL) & 0x8000;
BOOL bShift = ::GetKeyState( VK_SHIFT) & 0x8000;
BOOL bAlt = ::GetKeyState( VK_MENU) & 0x8000;
switch( pMsg->wParam)
{
case VK_ESCAPE: //不能Esc就退出程序
if(AfxGetApp()->GetProfileInt("General", "Tray", 1))
{
ShowWindow( SW_MINIMIZE);
ShowWindow(SW_HIDE); //隐藏动画
}
else
{
ShowWindow( SW_MINIMIZE);
}
return TRUE; //必须要立即返回
break;
case VK_RETURN:
if( bCtrl)
{
SendMessage( WM_COMMAND, IDC_SEND);
return TRUE;
}
break;
case 'J':
if( bCtrl)
{
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);
return TRUE;
}
break;
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
m_toolTip.RelayEvent(pMsg); //
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
return CDialog::PreTranslateMessage(pMsg);
}
void CSecretChatDlg::OnUsername() //查看用户的私钥信息
{
CSecretKeyEdit secretKeyEditDlg;
secretKeyEditDlg.m_select = SECRETKEY_PRIVATE;
if(secretKeyEditDlg.validateSecretKey(
m_appName
+ "\\user\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey"))
!= SECRETKEY_PRIVATE)
{
MessageBox(
"不是用户私钥文件",
"密聊",
MB_ICONINFORMATION);
return;
}
secretKeyEditDlg.DoModal();
}
void CSecretChatDlg::OnFriendname() //查看好友的公钥信息
{
CSecretKeyEdit secretKeyEditDlg;
secretKeyEditDlg.m_select = SECRETKEY_PUBLIC;
if(secretKeyEditDlg.validateSecretKey(
m_appName
+ "\\friend\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey"))
!= SECRETKEY_PUBLIC)
{
MessageBox(
"不是好友公钥文件",
"密聊",
MB_ICONINFORMATION);
return;
}
secretKeyEditDlg.DoModal();
}
BOOL CSecretChatDlg::AskPublicKey() //请求获得连线好友的公钥文件
{
if(m_online)
{
MessagePackage msg;
msg.head = HEAD_CLAIM_PUBLIC_KEY;
SendData(msg, sizeof(msg));
return TRUE;
}
else
{
MessageBox(
"需要联机才能请求获得对方的公钥文件",
"密聊",
MB_ICONINFORMATION);
return FALSE;
}
}
BOOL CSecretChatDlg::ClaimPublicKey(MessagePackage &msg) //请求对方的公钥
{
//生成公钥信息
SecretKey secretKey;
CFile file;
if(!file.Open(
m_appName + "\\user\\" + AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey"),
CFile::modeReadWrite | CFile::typeBinary))
return FALSE;
if(file.GetLength() != sizeof(SecretKey))
return FALSE;
file.SeekToBegin();
file.Read(&secretKey, sizeof(SecretKey));
file.Close();
//清除私钥信息
char chTemp[2048 / 8];
for(int i = 0;i < (2048 / 8);i++)
{
chTemp[i] = 0;
}
::MoveMemory(
(char *)&secretKey.sk, //目标
chTemp, //源内容
2048 / 8);
secretKey.privateOrPublic = SECRETKEY_PUBLIC;//公钥标记
msg.head = HEAD_REVERT_PUBLIC_KEY; //回复给对方
::MoveMemory(
msg.data, //目标
(char *)&secretKey, //源内容
sizeof(SecretKey)); //公钥文件信息包涵公钥文件名
SendData(msg, sizeof(msg));
return TRUE;
}
BOOL CSecretChatDlg::RevertPublicKey(MessagePackage &msg) //接收对方的公钥
{
SecretKey secretKey;
CSecretKeyEdit secretKeyEditDlg;
CString fileName;
CFile file;
CFileFind find;
::MoveMemory(
(char *)&secretKey, //目标
msg.data, //源内容
sizeof(SecretKey)); //公钥文件信息包涵公钥文件名
fileName = //密钥的文件全路径
m_appName
+ "\\friend\\"
+ secretKeyEditDlg.CharToCString(secretKey.userName, 32)
+ ".pk";
if(find.FindFile(fileName)) //文件存在
{
MessageBox(
"对方的公钥文件 "
+ secretKeyEditDlg.CharToCString(secretKey.userName, 32)
+ ".pk 已经存在",
"密聊",
MB_ICONEXCLAMATION);
return FALSE;
}
//生成公钥文件
file.Open(
fileName,//密钥的文件全路径
CFile::modeCreate | CFile::modeReadWrite | CFile::typeBinary);
file.Write(
&secretKey,
sizeof(SecretKey)); //写入信息
file.Close();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -