MFC工作日记

来源:互联网 发布:剑三温柔花哥捏脸数据 编辑:程序博客网 时间:2024/06/06 13:12

double(*)() (*e)[9]; 指向函数指针数组的指针。
int (fun[5])(int ); 函数指针数组。
规律是从名字开始,先看右侧,再看左侧。

当你向一个MFC的exe工程文件添加OCX控件后,运行时,出现了如下对话框
这里写图片描述

两种解决办法,一个是右键你的工程,设置为活动工程。
第二:右键工程,setting,第二个选项,“调试里面”路径看看是不是正确,其实运行按钮就是在执行这个路径的文件。

16/08/30
今天我写了个控件,是调用底层库的,就是赤峰那个项目的,他们提供的底层库的入参是string类型,我在typedef函数指针的时候,发现MFC并没提供这个类型,我就手动添加了命名空间和头文件,然后写个Demo测试下,传了string的参数进去,也试了传char*进去,程序都崩溃,将函数指针处的string声明成char * 就不崩溃了,至今没弄明白为什么。

16/08/31
http://blog.sina.com.cn/s/blog_69922f3701016syd.html
这是个用来解决vc6.0环境问题的文章,解决的路径问题,如果以前安装过vc6.0,卸载后再安装,可能出现问题。

http://www.cnblogs.com/GeekYang/p/3905854.html
这个是指导filetools使用的文章,解决uc和office冲突的问题。

16/09/01
1)当你用一个demo调试ocx时,如果ocx被重新编译了,但是它的成员数目名字都没变化,直接在demo的根目录下把ocx替换即可,但是如果变了,必须要修改在demo引入的ocx.cpp和ocx.h,按照格式修改即可。
2)程序崩溃多半都是传参的时候参数类型问题,或者是数组越界(基本都是字符串长度没开够),或者有某个全局变量在方法里被重定义了。这些都是VC检测不出来的。

16/09/02
1)给你一个底层库的接口,参数列表里有出参和入参,这种形式是同步的,就是程序按顺序执行,最后给出参赋值。
而线程,就变成异步的了,就是说你想什么时候得到出参就什么时候得到,是异步的。
但是可以用ocx的事件来解决。PostMessage这个函数,将消息放到消息队列中,该函数将一个消息放入(寄送)到与指定窗口创建的线程相联系消息队列里,不等待线程处理消息就返回,是异步消息模式。消息队列里的消息通过调用GetMessage和PeekMessage取得。
这里写图片描述 如图的ocx类,它有个事件,右键它就可以添加事件了。

http://blog.csdn.net/blueln/article/details/7631096这有篇说MFC消息的文章。

http://blog.csdn.net/xman_2009/article/details/5618813 有关m_hWnd窗口句柄的文章。

应用和驱动传递数据,有种方法是通过事件,不是都通过接口的出参入参的。应用可以直接来访问事件获得信息。在异步线程里得到的信息,把信息给事件,应用就可以读啦!这是给事件发消息。

这里写图片描述
这是事件
这里写图片描述

16/09/05
将函数指针typedef一下不只是在之后调用的时候省事这个好处,当你要调用dll时,你可以将这个指针定义成你dll里面的函数名,这样在编译的时候可以顺便检查dll里的函数是不是跟系统函数重名了。

16/09/06
当打开一个vc++工程时,提示“不能访问类查看信息文件 类查看信息将不可用”,解决办法为:删除掉目录中clw及ncb文件,再打开,就可以了。

16/11/11
做非接的通信OCX,找不到dll里哪个是用来通信的函数,前辈告诉我搜索send,一般通信会用send做名字。

16/11/14
今天上司让我把返回的数据传到属性里,一开始不明白,后来学习,指的是控件属性,在《VC深入详解》的678页有介绍。于是有疑问,控件属性和成员变量有什么区别么,何必多此一举呢,老员工告诉我说:因为线程是异步的,参数只能同步返回,这是一点,其他区别也有,你都看看吧,待补充。。。。

16/11/16
安徽那个项目的SP代码,读卡器的。
这是一个读卡器的代码,sp的,这里往服务层发消息了。
这里写图片描述
然后跟下去,到服务层,只找到了裸的消息响应函数
这里写图片描述
这里困惑了,服务层怎么会没收消息,没有调用这个响应函数的地方,后来经过大神教导,才知道还有关联消息的东西on_message

搜索OnServRequest,出来下面的找到这里
这里写图片描述
原来sp用了自定义消息响应函数,具体
http://blog.csdn.net/foreverhuylee/article/details/25394401

2016/11/17
Handle (看定义其实是void*)是代表系统的内核对象,如文件句柄,线程句柄,进程句柄。
HMODULE 是代表应用程序载入的模块,win32系统下通常是被载入模块的线性地址。
HINSTANCE 在win32下与HMODULE是相同的东西,在Win32下还存在主要是因为win16
程序使用HINSTANCE来区别task。
HWND 是窗口句柄。

互斥对象
互斥对象也是种内核对象
一。
Handle hMutex = CreateMutex( NULL , Falese , NULL) ;创建互斥匿名对象。
注意点:
1)创建互斥对象的线程拥有互斥对象所有权,要想给其他线程用,先释放。
2)创建互斥对象的线程也可以用 WaitForSingleObject申请所有权的,只不过是在互斥对象的计数器里递加一次而已,你取得多少次所有权,就要释放多少次。
3)有时候你发现自己的线程里没有释放,也成功的把资源所有权让其他线程得到了,那肯定之前的线程执行结束了,执行结束的话是会释放所有权的,即把互斥对象的线程ID置为0,计数器置为0.

二。
ReleaseMutex函数,释放互斥对象所有权。(并不是消除)

三。
WaitForSingleObject(hMutex,INFINITE)函数,让多线程互斥的关键函数。取得互斥对象所有权。
他的返回状态可以知道当前线程所得到的所有权是正常得到的(RealseMutex),还是WAIT_ABANDONED前线程结束得到的,后者有可能是发生了异常,所以要小心处理。

具体详见:《VC深入详解》572-578
下面是返回值说明
这里写图片描述

四。
如果你希望你的进程是不可以打开多个的,你可以这样
这里写图片描述

在你的主线程里创建完线程后,判断返回的句柄有效,那么你再调用GetLastError()这个函数,如果返回的事ERROR_ALREADY _EXISTS那么证明这是个命名的互斥对象已经被创建了。

2016/11/18
MFC定时器
看服务层代码,发现和SP层代码不同的地方有很多,最令我在意的地方是服务层为什么不是多线程呢,在代码里搜不到建立线程的函数,然后知道了有定时器这种东西。

先说创建方法,一图流:
这里写图片描述

计时器的基类是对话框,所以得选xxxDlg。

程序代码中将自动添加函数OnTimer(UINT nIDEvent),在该函数内编写代码实现计时器功能。
函数代码一般写在switch…case中,nIDEvent表示计时器ID号,从而区分不同计时器的实现内容。
若不使用switch…case结构,则表示实现ID为1的计时器功能。
例如下列函数代码:

void CCountDown::OnTimer(UINT nIDEvent)
{
switch (nIDEvent)
{
case 1:
{

//代码实现

break;
}
default:
break;
}

CDialog::OnTimer(nIDEvent);
}

在要开始计时器的地方调用:

SetTimer(1,1000,NULL);//
第一个参数表示计时器的ID;
第二个参数表示间隔时间(ms);
第三个表示调用的函数,NULL表示默认调用OnTimer函数。

在要结束计时器的地方调用:

KillTimer(1);) //参数表示计时器的ID;

定时器和线程的不同(摘自百度):
定时器是在某个时间到了执行一次代码,他的执行与否完全取决于时间,而线程os回给他分配内存空间后,他会完全向主线程一样去线程队列中等待,因此,定时器是抢占式的执行,只要时间到了,由于很高的优先级,会立马执行,影响程序执行速度,而线程则会和其他线程进入排队等待。
两者用途也不同,线程是为了并发执行,实现程序的同步,而定时器只是做一些必须定期做的工作,如刷新窗口之类的。

16/11/24
GetLastError()获取错误码,返回值是DWORD
今天碰到怎么加载都加载不上动态库的情况,气的要死,用这个获取到错误0x3E6,百度也查不出错误,最后发现那个库是有关联库的,没放在相应目录里,坑死。

16/12/15
http://www.cnblogs.com/dongsheng/p/4460944.html
关于共享内存的很简洁的例子,就是喜欢这样的。

http://www.cnblogs.com/xiekeli/p/4018579.html
共享内存深一些的知识。

16/12/11
1.CWinThread::CreateThread是实现界面线程用的,之后运行Run()就可以启动线程了,Run()是虚函数,重写即可。

邢台的示例代码就是例子。

2.EXE工程中,添加功能的方法:
建立个类,继承自CWinThread的类,声明这个类的对象,然后用对象去做实现功能,这个类里面有用户界面线程,默认的虚函数是Run(),下面说下Run()的重写方法。

右键所建立的类,点击“添加虚函数”,弹出如下:
这里写图片描述
这里的Run应该是在左侧的,你可以点击选中他,然后点选右侧的“Add Handler”即可添加成功。

3.带钥匙的,就是protect类型,不能跨类使用。

4.虽然你发现自己声明了全局变量,但是在使用的时候还是报了未声明的错误,原因是你的源文件不是一个,跨类使用了这个变量,你可以在要使用 的地方前面加例如:extern int x;
你发现就可以跨类使用他了。

2016/12/22
这里写图片描述
这是个继承自CWinThread的类,他的对象实例化时,执行顺序是,ReadCard()构造函数,InitInstance()入口。ExitInstance(),最后析构函数~ReadCard()。

2016/12/22
今天写个EXE,里面加载了动态库,设置的目录是当前目录,然后把EXE单独提出来,放别的目录下,发现还是加载成功动态库,很奇怪,后来得知LoadLibrary这个函数,加载是有如下顺序的:

当前进程的可执行模块所在的目录。
当前目录。
Windows 系统目录。GetSystemDirectory 函数检索此目录的路径。
Windows 目录。GetWindowsDirectory 函数检索此目录的路径。
PATH 环境变量中列出的目录。

我的环境变量里的目录下,确实放了个相应动态库(自己都不知道)。

2016/12/26
还是老话题,程序崩溃,这次很恶心,因为找不到断点,这样的,项目是江苏银行的那个,非接模块,寻卡+上电+发指令,崩溃点是在上电和发指令上,不一定在这两处哪里崩,也可能不崩,也可能程序都走完了,你点击关闭测试页面的时候崩,草拟吗。原因都是因为这个变量类型:LPCTSTR。
这个变量类型是字符串类型指针,但是它是只读的,不能作为出参来给他赋值。就这么小小的细节。

2016/12/27
今天给线场发了控件,用网页版测试工具测试,在我这什么问题没有,在现场就直接崩了,是那种一加载控件就崩,都到不了点按钮那步。后来咨询老师,老师说不要在控件类构造函数里加载动态库,于是声明了成员函数类实现这功能,结果不崩了。老师说让我看看看看构造函数,析构函数,动态库的加载,控件的加载,这里待续。。。

2016/12/28
js相关,教你怎么反应控件事件。
http://www.xuebuyuan.com/1242748.html

江苏银行二合一文档里有相应网页例子

2016/12/29
js相关,教你怎么反应控件事件。
http://www.iteye.com/problems/41865

0 0