关于多线程和UI的问题~

blz_wowar 2010-10-18 11:42:51
2个线程。
我在主线程里面创建了主窗口,然后建立一个子线程去创建一个Button到这个主窗口上。
但是跑起来的时候,看不到按钮。
在Debug模式下,能看到创建Button成功了,返回的Windows Handle不是空的。
但是在Release模式下,我用SPY++去看,却看不到这个按钮的。

对消息回路,多线程以及UI不是很了解,有兄弟交流一下吗?谢谢~
...全文
283 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
blz_wowar 2010-10-20
  • 打赏
  • 举报
回复
也是,先给分,到时候,不懂的再开帖了。。。
谢谢~
babala2009 2010-10-19
  • 打赏
  • 举报
回复

这个问题 看看书吧,一言2语说不上来




[Quote=引用 19 楼 blz_wowar 的回复:]

我测试一下,我的也可以了,按钮可以看到了,
原因是我的代码之中没有消息泵
MSG msg;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}

加上这段就能看到按钮了。

babala2009,你知道为什么吗?很有疑问。……
[/Quote]
blz_wowar 2010-10-19
  • 打赏
  • 举报
回复
而且是主窗口刚创建出来的时候,是还看不到按钮的,但是鼠标移动上去之后就有了,之后就能一直看到了,我想这个可能只是一个刷新问题。

至于为什么要加这个消息泵,想了又想,想不通。。。
blz_wowar 2010-10-19
  • 打赏
  • 举报
回复
我测试一下,我的也可以了,按钮可以看到了,
原因是我的代码之中没有消息泵
MSG msg;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}

加上这段就能看到按钮了。

babala2009,你知道为什么吗?很有疑问。。。。。
我对消息循环不是很懂。
wltg2001 2010-10-18
  • 打赏
  • 举报
回复
上代码看看吧。
傻X 2010-10-18
  • 打赏
  • 举报
回复
楼主的做法好奇怪哦
为啥要另外一个线程去创建呢?
主线程创建好然后隐藏,依靠另外一个线程控制该按钮显示.这个效果和你的需求一般吧.尝试下看看
babala2009 2010-10-18
  • 打赏
  • 举报
回复
上代码看看!
babala2009 2010-10-18
  • 打赏
  • 举报
回复
我怀疑不是看不到,是代码的问题。他可能是直接在新的线程中CreateWindow(BUTTON...),然后就退出了。

新线程
NewThread(....)
{
..............
MSG msg;
while(1)
{
.................
}

}
job82824 2010-10-18
  • 打赏
  • 举报
回复
创建的是自绘按钮的话肯定看不到
babala2009 2010-10-18
  • 打赏
  • 举报
回复
[Quote=引用楼主 blz_wowar 的回复:]
2个线程。
我在主线程里面创建了主窗口,然后建立一个子线程去创建一个Button到这个主窗口上。
但是跑起来的时候,看不到按钮。
在Debug模式下,能看到创建Button成功了,返回的Windows Handle不是空的。
但是在Release模式下,我用SPY++去看,却看不到这个按钮的。

对消息回路,多线程以及UI不是很了解,有兄弟交流一下吗?谢谢~
[/Quote]

消息循环搞错了吧!
leeihcy 2010-10-18
  • 打赏
  • 举报
回复
上代码
babala2009 2010-10-18
  • 打赏
  • 举报
回复
我的没有问题:
我是在原来的界面上增加一个subdlg。

DWORD WINAPI CSkinFrame::ThreadUI(__in LPVOID lpParameter)
{
CSkinFrame *pSkinFrame = (CSkinFrame*)lpParameter;
if (pSkinFrame)
{
CDlgSub Dlg;
Dlg.Create(pSkinFrame->m_InfoPan.m_hWnd);
pSkinFrame->m_InfoPan.SetClient(Dlg.m_hWnd);
Dlg.ShowWindow(SW_SHOW);

MSG msg;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}

}
return 0;
babala2009 2010-10-18
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 blz_wowar 的回复:]

我汗。。。。补充说明一下

1. 我的工程是ATL/WTL工程。
2. 消息循环有的,不过我只是贴了一段示例代码。
3. 那篇文章里面貌似提到了,原因是和 Thread TLS有关。

等我细看了,也许能在和你交流一下。谢~
[/Quote]

应该没有关系!
过一段时间 我也做一个类似的东西!看看什么问题
blz_wowar 2010-10-18
  • 打赏
  • 举报
回复
我汗。。。。补充说明一下

1. 我的工程是ATL/WTL工程。
2. 消息循环有的,不过我只是贴了一段示例代码。
3. 那篇文章里面貌似提到了,原因是和 Thread TLS有关。

等我细看了,也许能在和你交流一下。谢~
blz_wowar 2010-10-18
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 babala2009 的回复:]

引用 9 楼 blz_wowar 的回复:

主线程里面的代码:
。。。
HANDLE handle = ::CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
if(handle)
::CloseHandle(handle);
。。。


CButton button;
HWND hwnd = NULL;
DWORD WI……
[/Quote]

这个其实只是一个验证代码,因为我有一个很复杂的UI框架之中出现了这个问题,所以我写了个最简单的Sample来验证。
另,hwnd有值,我在Debug状况下调试过,按钮都被创建起来了,能得到创建按钮获取到handle。
最后,我用你写的代码试试看.

另外MFC程序也有这样的问题,
http://msdn.microsoft.com/en-us/library/h14y172e(v=VS.80).aspx
有关于类似的描述,但是我还没仔细看。提供给大家,做下参考看。
谢谢~
jinru2560 2010-10-18
  • 打赏
  • 举报
回复
窗体木有及时刷新吧
babala2009 2010-10-18
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 blz_wowar 的回复:]

主线程里面的代码:
。。。
HANDLE handle = ::CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
if(handle)
::CloseHandle(handle);
。。。


CButton button;
HWND hwnd = NULL;
DWORD WINAPI ThreadProc(LPVOID lp……
[/Quote]

好我想的一样。这个是错误的做法。
个人意见是:你没有必要再线程中创建button。
同时你的代码有问题:
Create(hwnd, rc, NULL, WS_CHILD | WS_VISIBLE);
hwnd应该是对话框窗口句柄,不知道是否赋值了。

你缺少消息循环,如下面代码。线程需要类似的代码。
int Run()
{
BOOL bDoIdle = TRUE;
int nIdleCount = 0;
BOOL bRet;

for(;;)
{
while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!OnIdle(nIdleCount++))
bDoIdle = FALSE;
}

bRet = ::GetMessage(&m_msg, NULL, 0, 0);

if(bRet == -1)
{
ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n"));
continue; // error, don't process
}
else if(!bRet)
{
ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n"));
break; // WM_QUIT, exit message loop
}

if(!PreTranslateMessage(&m_msg))
{
::TranslateMessage(&m_msg);
::DispatchMessage(&m_msg);
}

if(IsIdleMessage(&m_msg))
{
bDoIdle = TRUE;
nIdleCount = 0;
}
}

return (int)m_msg.wParam;
}
blz_wowar 2010-10-18
  • 打赏
  • 举报
回复
是啊,就是在线程里面创建一个按钮,但是我发现主窗口上没看到有这个按钮,为什么?
是我程序写错了,还是本来Windows机制就不允许这种情况?

Eleven 2010-10-18
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 blz_wowar 的回复:]
主线程里面的代码:
。。。
HANDLE handle = ::CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
if(handle)
::CloseHandle(handle);
。。。


CButton button;
HWND hwnd = NULL;
DWORD WINAPI ThreadProc(LPVOID lpP……
[/Quote]
在线程中创建按钮?
blz_wowar 2010-10-18
  • 打赏
  • 举报
回复
主线程里面的代码:
。。。
HANDLE handle = ::CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
if(handle)
::CloseHandle(handle);
。。。


CButton button;
HWND hwnd = NULL;
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
RECT rc = {0, 50, 100, 150};
HWND hh = button.Create(hwnd, rc, NULL, WS_CHILD | WS_VISIBLE);
return 0;
}
这是线程函数,参数传递上没问题,我检查过了
其实为了简单期间,我一些参数都使用了全局。
帮忙看看
加载更多回复(1)

15,979

社区成员

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

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