lydit的博客


  • 首页

  • 标签

  • 分类

  • 归档

  • 搜索

(转载)注意:PreTranslateMessage弹出框出错

发表于 2017-12-14 | 分类于 C/C++
字数统计: 1,255字 | 阅读时长 ≈ 5分钟

dlg.DoModal()截住了界面消息,所以返回时原来的pMsg的内容已经更改了,消息,窗口句柄都不在是if以前的值了,而且窗口句柄应该是对话框里的子窗口的句柄,所以调用CFrameWnd::PreTranslateMessage(pMsg);
时pMsg的窗口句柄是个无效值(窗口已销毁)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
BOOL CViewUP::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
if(pMsg->wParam =='M' || pMsg->wParam == 'm')//暂时为按“M”键退出系统
{
AfxGetApp()->m_pMainWnd->SendMessage(WM_CLOSE,0L,0L);
return TRUE;
}
else if(pMsg->wParam=='Z' || pMsg->wParam == 'z')//暂时为按“Z”键启动就地系统
{
//激活上一个窗口还是退出??因须要而定
CWnd* pWnd = FindWindow(NULL,_T("就地站_JD"));
if (pWnd)
{
pWnd->ShowWindow(SW_SHOWNA );//SW_SHOWMAXIMIZED);
pWnd->SetForegroundWindow();
return TRUE;
}
// CAONumValueDlg aoDlg;
// aoDlg. DoModal();
}
}

return CView::PreTranslateMessage(pMsg);
}

注意事项

模态窗口极大地简化了一些需要和用户交互的操作,好处显而易见。但这里还是要指出一些需要注意的地方,否则使用的时候很可能会出问题。

影响PreTranslateMessage机制

在使用MFC,WTL等进行开发的时候,经常用到PreTranslateMessage机制,这个机制可以让我们在消息被派发之前先做一些事情。很多人以为PreTranslateMessage是Windows本身支持的,其实不然。PreTranslateMessage是MFC和WTL自己引入的一个概念,完全是和Windows无关的。在MFC和WTL的消息循环中,这两个库的设计者在消息分发之前,人为的加了一些代码,使得整个架构支持这一套机制。

正是如此,如果在正常的流程中弹出了模态窗口,就会使正常的PreTranslateMessage机制失效。因为模态窗口中已经包含了一个消息循环,接管了线程中缺省的消息循环。而这个消息循环是在DialogBox这个API函数中执行的,显然不可能再有PreTranalateMessage机制了。

为了解决这一问题,只有让模态窗口也使用和UI线程相同的消息循环,MFC正是这么做的。在MFC中,对话框类的DoModal函数,并不是调用DialogBox函数,而是直接使用CreateWindows创建一个非模态窗口,在窗口创建成功之后再调用MFC自己的消息循环,这样就可以让PreTranslateMessage继续生效。同时在窗口创建出来之后,必须再做一些别的操作,使这个模态窗口的父窗口失效(一般直接把窗口Disable掉)。同时消息循环里有合适的退出条件,并有恢复现场的一些操作,具体可以查看MFC的DoModal函数。

WTL到目前为止,貌似暂时还没有一个合适的方案来解决这个问题。事实上WTL的PreTranslateMessage机制实现的其实是有点问题的,或许以后会在这方面做一定的增强。

可能导致崩溃

这是一个严重问题,在条件合适的情况下,这个崩溃是必然的。

因为模态窗口弹出来之后,模态窗口后面的代码在窗口关闭之前将不会得到执行。然而此时整个窗口是在正常运行的,对于一些极端的情况,是极有可能造成崩溃的。下面看一个例子:

1
2
3
4
5
6
7
8
9
void CTestDlg::OnOK()
{
CInputDialog dlg;
If(dlg.DoModal() == IDOK)
{
m_nValue = dlg.GetValue();
UpdateData(FALSE);
}
}

这是一段典型的MFC代码,在绝大多数情况下,不会有任何问题。但是由于模态窗口弹出的时候,只是父窗口不能操作,但别的窗口完全还能正常运行,这时候就非常有可能由于某种原因,CTestDlg类已经销毁了,而CInputDialog却不知道,还在继续执行,结果到了IDOK之后,对CTestDialog类的成员变量m_nValue赋值,就会出现崩溃了。

这个问题,如果在多线程的情况下,将会更加严重。因为在多线程的情况下,将会有更加多的不可预料的因素,所以使用的时候要更加小心。

改成这样就OK了,

1
2
3
4
5
6
7
8
9
if (pMsg-> message == WM_CHAR)
{
MSG msg = *pMsg;//后来发现这样还是有点问题,模态对话框回车后,鼠标不见了
CMyDlg dlg;
dlg.DoModal();
*pMsg = msg; //后来发现这样还是有点问题,模态对话框回车后,鼠标不见了

return TRUE;//最终方法还是在这里直接返回吧,破坏消息循环总是不好的。
}

我估计是MFC保存了一个当前消息的结构来跟踪消息路由,dlg.DoModal();时这个结构的值都更新好多遍了

/////注意///下面是自己实践的代码

1
2
3
4
5
6
7
8
9
10
11
12
BOOL CDoctorAdd::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->hwnd==((CButton*)GetDlgItem(IDOK))->m_hWnd && pMsg->message==WM_MOUSEMOVE)
UpdateData();
if(m_number.IsEmpty())
{
CMyDlg dlg;
dlg.DoModal();
//return CDialog::PreTranslateMessage(pMsg);
return true;
}
}

//呵呵这样就不报错啦

转自:http://blog.sina.com.cn/s/blog_9e2e84050101fnjk.html

(转载)对于代码审查的认识和理解

发表于 2017-12-14 | 分类于 编程思想
字数统计: 1,377字 | 阅读时长 ≈ 5分钟

代码审查应该成为任何重要的软件开发工作中一个基本制度。并不单指产品程序――而是所有东西。而且代码审查也不需要花费很多的时间和人力,但它却能发挥巨大的效果。

从代码审查里能得到什么?

对于代码审查的认识,在代码提交前,用其他人的眼睛检查一遍,防止bug混入。这是最常见的理解,也是对代码审查的好处的最广泛的认识。

但是,在我看来,这并是它最不重要的。人们确实可以在代码审查中找到一些bug。可是,这些在代码审查中能发现的绝大部分bug,很显然,都是微不足道的bug,程序的作者花几分钟的时间就能发现它们。真正需要花时间去发现的bug不是在代码审查里能找到的。

代码审查的最大的好处在于,如果你是程序员,而且知道将会有其他同事来检查你的代码,你编程态度就完全不一样了。你写出的代码将更加整洁,有更好的注释,更好的程序结构。因为你很在意别人对你的程序的看法。没有代码审查,你可能会认为,你写的程序基本不会有人看到,除非有人用到了,它不会给你带来同等的紧迫感。除此之外,还有一个非常重要的好处。代码审查能传播知识,培养分享的氛围。在很多的开发团队里,经常每一个人负责一个核心模块,每个人都只关注他自己的那个模块。除非是同事的模块影响了自己的程序,他们从不相互交流。这种情况的后果是,每个模块只有一个人熟悉里面的代码。如果这个人休假或辞职了,其他人则束手无策。通过代码审查,至少会有两个人熟悉这些程序。审查者虽然并不能像程序的作者一样对程序和业务十分了解,但他会熟悉程序的设计和架构还有业务的架构,这个极其重要的。

刚开始,大家在代码审查时经常会犯一些错误,导致很多麻烦,特别是一些缺乏经验的审查者,他们在代码审查的时候会给了程序开发者的很不好的感觉,最终导致程序员抵触代码审查制度。

针对所有人的审查
    * 首先必须承认:审查者都是根据自己的编程习惯来评判别人的代码。所以很多编程上的主张都是一种个人观点。所以应该讨论它们的利与弊,提出你倾向的观点,迅速的在团队达成一致。

  • 对与审查者和被审查者,大家觉得有压力,感觉非要说点什么,非得找出点什么问题出来才好,别人都提出了点什么,自己多少也得说点吧。(完全不需要。只说一句“这段程序写的真不错。”就可以了)

  • 尽量使用提问或是建议,而不是命令。(“把这个变量命名成:user_id,你觉得怎样?”)

  • 请求说明。(“我不明白。你能解释一下吗?”)

  • 避免代码的归属之争。(“我的”,“不是我的”,“你的”)

  • 不要讽刺,嘲笑别人的代码,避免使用一些会被认为或可能会被认为是有关人身特征的词语。(“笨蛋”,“愚蠢”,“傻逼”,“二”)要把所有人都看作是有魅力的、聪明的、善意的。

  • 要明确。要记着并不是每个人都能理解你的意图。

  • 要谦虚。(“我不能确定——我们来分析一下。”)

  • 不要用“总是”,“从不”,“永远”,“毫无…”这样的修辞语。

  • 如果对于某个代码,有太多的我不理解或大家都有不同的看法,可以组织一个讨论会,或是技术分享,然后把你们的交流形成共识,总结成文档

  • 代码审查,不能时间太短,这样没有太多的效果,但是时间也不能太长。毕竟大家还有其他的工作要做。

让别人审查你的代码

  • 首先要达成共识,理解审查是对事不对人。审查的是你的代码,而不是你。

  • 对审查者的建议表示肯定和感激。(“对,你说的没错。”,“谢谢提醒。我会把它改正。”)

  • 解释为什么代码写成这样,可以说明这段代码的业务逻辑。

  • 整理所作的改动,不必当场改掉,复杂的程序,也可以在以后的迭代中重构它们。

  • 努力站在审查者的立场上理解,同样也要努力理解作者的立场。。

  • 针对你感觉非常好的地方以及不是很好的地方与开发者交流。

  • 找出既能解决问题又能简化代码的方法,让代码变得简单。

  • 提出你的实现方案,但要表现出作者也在考虑这种方案。(“你觉得这里用一个自定义校验如何?”)

  • 程序风格样式和注释,同样也是代码审查的范围,而不仅仅是程序。

原文地址:http://www.cnblogs.com/zhangweizhong/p/4389884.html

(原创)vs2013编程64位程序连接access数据库

发表于 2017-12-14 | 分类于 C/C++
字数统计: 225字 | 阅读时长 ≈ 1分钟

之前一直是vc6上开车,今天因为测试需要,转到了vs2013,之前就写写底层的,还没搞过数据库的,发现网上资料还是很杂乱的,故自己整理了一份出来
具体的类已经上传到百度网盘了,所以这边就简单点了,写下调用的代码就好了
初始化数据库

1
Init_DataBase();

调用查询显示数据库

1
2
3
4
5
6
7
8
9
10
11
12
DBTable hDBTable;
DWORD dwCount = DataInertface_GetCount(&hDBTable);
int nLogID = 0;
for (int i = 0; i < dwCount; i++)
{
nLogID = 0;
if (DataInertface_Read(&hDBTable,&nLogID))
{
DebugOut("[Ht64Bit]nLogID=%d",nLogID);
}
}
hDBTable.Close();

补充:
之前碰到个问题,就是在编译机器运行正常,但是到目标机器的话,就会出错,最后是安装了AccessDatabaseEngine_X64.exe之后才解决的

百度盘地址
链接: https://pan.baidu.com/s/1o7CtHBO 密码: k4n4

原创文章,转载请标原文地址

Hello World

发表于 2017-12-13
字数统计: 78字 | 阅读时长 ≈ 1分钟

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

123
lydit

lydit

24 日志
3 分类
18 标签
© 2017 — 2020 lydit | 总字数: 11.9k
个人专属
|
博客 — lydit
本站访客数 人次 本站总访问量 次
0%