Board logo

标题: [其他] TG的程序员进。。。问一个有关UI多线程获取对话框指针的问题。。。。 [打印本页]

作者: shixn    时间: 2013-6-30 00:06     标题: TG的程序员进。。。问一个有关UI多线程获取对话框指针的问题。。。。

简单的说

在 对话框A(对应类A) 上有一个 按钮1 ,按一下就弹出来一个 对话框B ,这个 对话框B(对应类B) 是UI多线程做的。

现在想实现的功能是,在 对话框B 里,显示 对话框A(类A) 里一个 变量x 的值。

我想的方法是,在 对话框B 里获得 类A 的指针,但是不知道如何操作。。。

网上搜了半天看的一头雾水,求多快好省的方法

激骚伺候!!

再追加一个问题,就是如何在 对话框A 里获得 对话框B 的指针??

[ 本帖最后由 shixn 于 2013-6-30 00:40 编辑 ]
作者: lijgame    时间: 2013-6-30 00:16

posted by wap, platform: Chrome

什么os什么framework都没说。。。
如果是Windows下的话A创建B的时候保存句柄,然后变量值改变的时候把新的值以发消息的方式传递给B。
SendMessage是最简单的线程安全的消息机制了

好久没用过win32了,应该是这样的。。。
作者: seek    时间: 2013-6-30 00:31

A如果析构就杯具了~

多线程通信还是通过消息队列最可靠
作者: shixn    时间: 2013-6-30 00:37

引用:
原帖由 lijgame 于 2013-6-30 00:16 发表
posted by wap, platform: Chrome

什么os什么framework都没说。。。
如果是Windows下的话A创建B的时候保存句柄,然后变量值改变的时候把新的值以发消息的方式传递给B。
SendMessage是最简单的线程安全的消息机制了 ...
最基础的
win vc6

SendMessage里也需要 对话框B 的指针作为参数传递啊。。。
作者: shixn    时间: 2013-6-30 00:38

引用:
原帖由 seek 于 2013-6-30 00:31 发表
A如果析构就杯具了~

多线程通信还是通过消息队列最可靠
A是主线程,肯定不会析构
作者: seek    时间: 2013-6-30 00:41

仅仅是要获得指针的话,楼主听说过全局变量么?

当然全局变量都是尽量避免使用的,最好有一个manager,在创建B的时候,把A的指针注册进去,在A销毁的时候,再通知B把指针赋空。上面两个操作都要对指针加锁。
作者: SONIC3D    时间: 2013-6-30 00:45

你的设计思路不对,应该B获得A告诉它的A上的变量,甚至更好一点是应该数据和视图分离。

方案一:A告知B,B使用:
-B窗口为平台窗口类的派生类ClassWndB,构造函数接受一个参数,用来初始化ClassWndB的成员变量mValueX.
在该类的其他方法中完成对mValueX的使用,和窗口内控件的布局,最后调用继承的平台窗口类显示的方法显示B窗口本体。
-在A窗口对应的类实现中的按钮事件方法中,以A窗口的变量x值去构造ClassWndB的一个实例。
-完毕

方案二:数据与视图分离
另外建一个数据管理类DataMgr,存放变量X,同时含有对变量X存取的成员方法。
在A窗口类中的对应事件(比如控件值变化事件)中调用DataMgr类中写入变量X的成员方法。
在B窗口类中的对应事件(比如B窗口的onCreate)中调用DataMgr类中读取变量的成员方法。
A窗口类实例和B窗口类实例的初始化时由初始化方赋予DataMgr的同一个实例。
完毕。
备注:如果存在多线程访问存取,记得加锁,但是我觉得你的用例里说是UI多线程,但似乎不存在多线程同时访问存取的问题。
作者: shixn    时间: 2013-6-30 00:47

引用:
原帖由 seek 于 2013-6-30 00:41 发表
仅仅是要获得指针的话,楼主听说过全局变量么?

当然全局变量都是尽量避免使用的,最好有一个manager,在创建B的时候,把A的指针注册进去,在A销毁的时候,再通知B把指针赋空。上面两个操作都要对指针加锁。
全局变量知道,加锁不太懂。。。
作者: shixn    时间: 2013-6-30 00:54

引用:
原帖由 SONIC3D 于 2013-6-30 00:45 发表
你的设计思路不对,应该B获得A告诉它的A上的变量,甚至更好一点是应该数据和视图分离。

方案一:A告知B,B使用:
-B窗口为平台窗口类的派生类ClassWndB,构造函数接受一个参数,用来初始化ClassWndB的成员变量mV ...
这个思路我也想过,所以就产生了追加问题。。

“在A窗口对应的类实现中的按钮事件方法中,以A窗口的变量x值去构造ClassWndB的一个实例”

这个具体如何实现啊。。。

按钮1 的函数是:
void CUIDlg::OnButton1()
{
        // TODO: Add your control notification handler code here
        CWinThread *pThread=AfxBeginThread(RUNTIME_CLASS(CDlgB));
}
如何把X值传递给CDlgB?

方案二有点似懂非懂的感觉,俺再研究研究。。

[ 本帖最后由 shixn 于 2013-6-30 00:56 编辑 ]
作者: SONIC3D    时间: 2013-6-30 01:12

引用:
原帖由 shixn 于 2013-6-30 00:54 发表

这个思路我也想过,所以就产生了追加问题。。

“在A窗口对应的类实现中的按钮事件方法中,以A窗口的变量x值去构造ClassWndB的一个实例”

这个具体如何实现啊。。。

按钮1 的函数是:
void CUIDlg::OnBut ...
我操,MFC什么的最让我感觉青春黑暗无比了。。。。
你这样用线程的话,我建议还是认认真真思考第二种方案。
如果一定要用第一种方案,那么AfxBeginThread是有第二个参数的,请自己看MSDN,但明确说这样用从结构角度不好,纯属堆代码完成项目功能。


另外,我建议先通读阅读《设计模式》再写程序,我上面说的2种方案细节都没说得很全很详细,在这本书中你可以找到所有答案,更彻底更完全,即使不做码农,此书也可以在哲学角度对你的人生也有意义,书也不厚,2周可破。。。http://book.douban.com/subject/1052241/

[ 本帖最后由 SONIC3D 于 2013-6-30 01:15 编辑 ]
作者: shixn    时间: 2013-6-30 01:46

引用:
原帖由 SONIC3D 于 2013-6-30 01:12 发表

我操,MFC什么的最让我感觉青春黑暗无比了。。。。
你这样用线程的话,我建议还是认认真真思考第二种方案。
如果一定要用第一种方案,那么AfxBeginThread是有第二个参数的,请自己看MSDN,但明确说这样用从结构角 ...
AfxBeginThread函数有2种形式,工作者线程是有第二个参数的,UI多线程木有,所以比较伤脑筋……
CWinThread* AfxBeginThread(
   AFX_THREADPROC pfnThreadProc,
   LPVOID pParam,
   int nPriority = THREAD_PRIORITY_NORMAL,
   UINT nStackSize = 0,
   DWORD dwCreateFlags = 0,
   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);
CWinThread* AfxBeginThread(
   CRuntimeClass* pThreadClass,
   int nPriority = THREAD_PRIORITY_NORMAL,
   UINT nStackSize = 0,
   DWORD dwCreateFlags = 0,
   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);

现在确实就是为了完成任务,不然这周末大半夜的。。。。

实在不行就全局变量先凑合着。。。。

书名记下了,非常感谢,今天激骚没了,改天一定补上!!
作者: lvcha    时间: 2013-6-30 11:44

posted by wap, platform: GALAXY NOTE II

数据模型和gui要分离加一。
所有界面输入输出都是对后端的统一接口操作。
作者: iou90    时间: 2013-6-30 11:56

感觉7L说的很详细了啊
4人帮哪本书确实非常非常好
作者: lijgame    时间: 2013-6-30 13:46

posted by wap, platform: iPhone

一帮人真能扯,四人帮的书都出来了,楼主你要好一点解决方案就用mvc,要急就章的方案就用我说的发消息来解决。
作者: SONIC3D    时间: 2013-6-30 16:22

引用:
原帖由 shixn 于 2013-6-30 01:46 发表

AfxBeginThread函数有2种形式,工作者线程是有第二个参数的,UI多线程木有,所以比较伤脑筋……
CWinThread* AfxBeginThread(
   AFX_THREADPROC pfnThreadProc,
   LPVOID pParam,
   int nPriority = THREAD ...
看花眼了,以为你用了第一种
对于第二种AfxBeginThread,要往创建的CWinThread的派生类中加入成员变量并且设置,有两种方法
一种是AfxBeginThread调用的时候dwCreateFlags设为CREATE_SUSPENDED,之后置成员变量后再Resume
另一种是直接写一个CWinThread派生类的构造,然后调用CWinThread的CreateThread,而不是用AfxBeginThread。


如果赶工或者作业,那的确可以用消息队列完成,窗口B句柄在

CWinThread::m_pMainWnd和

CWinThread::m_pActiveWnd


如果是要长期维护下去的,建议还是好好设计好否则就是给自己挖坑,早晚给埋了。






欢迎光临 TGFC Lifestyle (http://tgfcer.com/) Powered by Discuz! 6.0.0