界面无响应的问题.

skyfree 2009-12-21 01:55:10
采用win32编写一个对话框程序
下面是我的程序的代码示例:

.....
case IDOK:
{
//disable the OK and Cancle button,防止用户多次点击
SetWindowText(GetDlgItem(hDlg, IDC_STATICERROR), L"Logging in ...... ");

EnableWindow(GetDlgItem(hDlg,IDOK), FALSE); //??这两个语句没有效果,
因为整个主线程被下面的login()阻塞了!
这个EnableWindow()也是通过发送message来响应,
但由于主线程被下面的语句阻塞,该message根本得不到处理,
所以不会 disable这个OK 按钮.
EnableWindow(GetDlgItem(hDlg,IDCANCEL), FALSE);

try
{
g_pShare->Login(); //这里要到服务器端验证,需要较长的时间....
}
catch ( ...)
{
SetWindowText(GetDlgItem(hDlg, IDC_STATICERROR), L"Connection failed! ");

EnableWindow(GetDlgItem(hDlg,IDOK), TRUE);
EnableWindow(GetDlgItem(hDlg,IDCANCEL), TRUE);
}

...... 进入主界面进行处理的代码





这段代码的问题就是 Login()这个方法阻塞了主线程,让使按钮变灰的指令无法真正执行。
解决方法我想是把 g_pShare->login()放到一个单独的线程中。 但是放到单独的线程中, 线程同步(waitforsingleobject)不是同样阻塞主线程么?还有由于多线程带来异常处理的问题。。。。

请问大家在这种情况下如何处理, 请给出详细的解决方案,主要是如何解决线程同步的阻塞和异常处理如何做的问题,谢谢了

...全文
290 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
hahaking119 2009-12-22
  • 打赏
  • 举报
回复
先禁用按钮,在登陆不成功的情况下启用按钮
心留 2009-12-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 cnzdgs 的回复:]
把login放到线程中,主线程在禁用按钮后创建线程,把按钮(或窗口)句柄作为参数传给线程,不等待线程结束直接返回,由线程在执行完Login后恢复按钮(或者给窗口发消息让主线程来处理)。
[/Quote]

同意
maple_zhj 2009-12-22
  • 打赏
  • 举报
回复
微软给出过一个方案。

你首先创建一个线程,去执行你的关键代码。

然后在主线程中,一直判断子线程是否执行完成,

并在每一次的判断后,重新 分发消息。
skyfree 2009-12-21
  • 打赏
  • 举报
回复
windows xp 下 正常, windows 7下 不正常, vista未测试
skyfree 2009-12-21
  • 打赏
  • 举报
回复
一去掉 主题, enablewindow工作就正常, 一加上就不好用了 :(
ycfh1ssvo1ss 2009-12-21
  • 打赏
  • 举报
回复
顶!
skyfree 2009-12-21
  • 打赏
  • 举报
回复
反复实验后发现了造成这个问题的原因, 大家说的不错, Enablewindow的确在大部分情况下是同步的,自己做了个小例子发现Enablewindow可以让按钮同步变灰。 但我现在用的是vista,而且程序中开启了window的theme, (加了.manifest文件,引入了uxtheme.lib库), 这种情况下, Enablewindow就失效了!!! (应该算是ms的bug吧), 请高手来解答一下,如何解决这个问题。
xwsn007 2009-12-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 cnzdgs 的回复:]
把login放到线程中,主线程在禁用按钮后创建线程,把按钮(或窗口)句柄作为参数传给线程,不等待线程结束直接返回,由线程在执行完Login后恢复按钮(或者给窗口发消息让主线程来处理)。
[/Quote]

同意。最好是postMessage让主线程处理界面
skyfree 2009-12-21
  • 打赏
  • 举报
回复
楼上说Enablewindow是同步的,是不是指MFC的enablewindow
我这里用的是API的enablewindow,发现确实不行呀。
topwork 2009-12-21
  • 打赏
  • 举报
回复
代码没有错误的,EnableWindow会立即使按钮实效,看看你的局部变量在运行时有没有什么问题吧。
sandyandy 2009-12-21
  • 打赏
  • 举报
回复
比如你灰了一个button后, 然后睡眠, button会变灰
GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
Sleep(1000000);
sandyandy 2009-12-21
  • 打赏
  • 举报
回复
EnableWindow调用是同步的, EnableWindow(GetDlgItem(hDlg,IDCANCEL), FALSE);
应该就是灰色的了
cnzdgs 2009-12-21
  • 打赏
  • 举报
回复
把login放到线程中,主线程在禁用按钮后创建线程,把按钮(或窗口)句柄作为参数传给线程,不等待线程结束直接返回,由线程在执行完Login后恢复按钮(或者给窗口发消息让主线程来处理)。

15,976

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧