Jul 6, 2008

对话框相关的话题

上次碰到一个问题
我要做A和B两个对话框,A为登陆,B为注册
实现的功能是A中若账号密码IP正确,点登陆,就能注销对话框进入主程序
若点A中的注册,则跳到B
若点A中的system menu里关闭按钮
则讲程序进程结束

对B而言,当填写注册资料验证无误后点注册
服务器接受数据并储存在数据库表单里后返回一个确认值及几个链表结构
则也注销对话框进入主程序,否则提示出错
若点B中的取消活着system menu的关闭
则返到A对话框

有一个问题
比如对于A,对话框的注销有三中情况
登陆成功,转到注册,关闭软件系统
而问题是按下Enter键后同样销毁了对话框(问题一)
这是因为它同样触发CDialog::OnOK虚函数处理OK键
而如何强制关闭当前进程??(问题二)
截取WM_CLOSE消息然后对三种情况用一个全局flag标志再在OnClose()函数里switch一下
这样也可以(现在想来)
不过我这里先给出当时我用的方法

首先截获WM_OK消息,将它的相应函数写为一个dummy function,即哑函数

void CLogIn::OnOK()//这里使用哑函数防止按下Enter就关闭对话框
{
//CLogIn是我写的登陆对话框类名
}

然后就先把退出软件系统这个功能解决了
即用户点A中关闭时,截获WM_CLOSE消息,处理函数如下

void CLogIn::OnClose() //当用户关掉登陆对话框,则进程结束
{
if(!isLogin)//m_socket与timer_socket是套接字部分,与本文无关
{
int end = 99;
send(m_socket,(char*)&end,sizeof(end),0);
send(timer_socket,(char*)&end,sizeof(end),0);
closesocket(m_socket);
closesocket(timer_socket);
}
m_pWnd=::GetCurrentProcess();//关键在这两个SDK函数
::TerminateProcess(m_pWnd,0);
}
然后解决登陆问题
void CLogIn::OnBtnLogin()
{
UpdateData(TRUE);
``` ``` ;//其他处理过程
CDialog::OnOK();
}
最后是跳到注册对话框问题
void CLogIn::OnBtnReg() //当用户选择注册时,调用注册对话框
{
UpdateData(TRUE);
CDialog::OnOK();
CRegister dlg;//CRegister是注册对话框类名
dlg.DoModal();
}

可以看到,Enter键的问题用哑函数解决了
而关闭系统进程的问题还有些有趣,连用两个SDK函数
其实还有一种做法,只有一句话,就是exit和_exit函数
在MSDN中对函数的说明如下
The exit and _exit functions terminate the calling process. exit calls, in last-in-first-out (LIFO) order, the functions registered by atexit and _onexit, then flushes all file buffers before terminating the process. _exit terminates the process without processing atexit or _onexit or flushing stream buffers. The status value is typically set to 0 to indicate a normal exit and set to some other value to indicate an error.

Although the exit and _exit calls do not return a value, the low-order byte of status is made available to the waiting calling process, if one exists, after the calling process exits. The status value is available to the operating-system batch command ERRORLEVEL and is represented by one of two constants: EXIT_SUCCESS, which represents a value of 0, or EXIT_FAILURE, which represents a value of 1. The behavior of exit, _exit, _cexit, and _c_exit is as follows.
可以直接一个exit(EXIT_SUCCESS)或exit(0)

这里之所以这么用是因为登陆对话框是在进入主程序前运行的
也就是说别的线程暂时还没有运行
如果此时别的线程(如监听线程等)已经运行
那么在OnClose()函数里要把所有该结束的线程也给结束了
比较麻烦
希望能找出一个快捷的方法

No comments:

Powered By Blogger