日记总结.docx
- 文档编号:10754365
- 上传时间:2023-02-22
- 格式:DOCX
- 页数:20
- 大小:30.40KB
日记总结.docx
《日记总结.docx》由会员分享,可在线阅读,更多相关《日记总结.docx(20页珍藏版)》请在冰豆网上搜索。
日记总结
关于对话框截获按键消息的处理方法1
对话框里开一个线程,如果在线程还没结束时就强制退出,则会出现内存泄露。
3
关于读取版本问题:
3
ShellExecute函数可以调用网站,安装文件等如4
在其他类中访问视图类的方法:
5
TCHAR与Cstring的比较5
对数据初始化,memcpy5
ClistCtrl用法:
6
使菜单不可用6
控件绑定步骤:
6
按钮自绘:
6
Onsyscommand10
关于对话框截获按键消息的处理方法
virtualBOOLPreTranslateMessage(MSG*pMsg);
功能:
OverridethisfunctiontofilterwindowmessagesbeforetheyaredispatchedtotheWindowsfunctionsTranslateMessageandDispatchMessage.Thedefaultimplementationperformsaccelerator-keytranslation,soyoumustcalltheCWinApp:
:
PreTranslateMessagememberfunctioninyouroverriddenversion.
重载该函数可以实现窗口消息在派发给窗口函数TrnaslateMessage和DispatchMessae()之前的过滤.缺省的实现是完成加速键的翻译.因为您必须在你的重载版本中调用CWinApp:
PreTranslateMessage()函数.
在MFC中,PreTranslateMessage是虚函数,我们可以重载它来处理键盘和鼠标消息。
在sdk中,这又有所不同,我们必须在回调函数中LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam)处理消息:
它和PreTranslateMessage起的作用是类似的。
只是MFC封装的更好而已
2.说明:
该函数表示在消息处理(TranslateMessge()和DispatchMessage()等)前所作的操作,如果函数返回值为TRUE,那么消息处理即终止,不会调用TranslateMessge()和DispatchMessage()来翻译和分发消息给相应的窗口;若返回值为FALSE,才会调用翻译和分发消息函数。
该函数是MFC消息控制流最具特色的地方,它是CWnd类的虚拟函数,通过重载这个函数,我们可以改变MFC的消息控制流程,甚至可以作一个全新的控制流出来。
在win32程序中,关于消息有两种传递方式:
a.MFC消息,MFC会把所有的消息一条条放到一个AFX_MSGMAP_ENTRY结构中,形成一个数组,该数组存放了所有的消息和与它们相关的参数。
也可以说是放到消息队列里去。
b.采用SendMessage()或其他类似的方式向窗口直接发送的而不经过消息队列的消息。
这两种方式中只有第一种(穿过消息队列的消息)才受PreTranslateMessage()影响,
第二种消息并不会理睬PreTranslateMessage()的存在。
一、是否调用TranslateMessage()和DispatchMessage()是由一个名称为PreTranslateMessage()函数的返回值决定的,如果该函数返回TRUE,则不会把该消息分发给窗口函数处理。
二、传给PreTranslateMessage()的消息是未经翻译过的消息,它没有经过TranslateMessage()处理。
可以在该函数中使用(pMsg->wParam==VK_RETURN)来拦截回车键。
三、在WindowProc里不能处理WM_Char消息。
(WindowProc函数见MFC消息响应机制一文)
四、SetWindowText会发送WM_Char给窗口。
五、PeekMessage和GetMessage的区别:
GetMessage在没有消息的时候等待消息,cpu当然低
PeekMessage没有消息的时候立刻返回,所以cpu占用率高。
因为游戏不能靠windows消息驱动,所以要用PeekMessage();
另一篇文章中:
在一个WIN32程序中,WINDOWS会将消息传递给相应的窗口。
但是消息不是立即就被传递给相应的窗口,而是会从整个程序最顶层的窗口传递到下一级窗口,再传递到下一级窗口,直到传递给目标窗口。
在整个过程中,有些消息,在某些特定的情况下,无法默认传递到目标窗口的。
比如用户在EDIT控件中按下回车键,CANCEL键等,如果EDIT窗口之前有对话框窗口,对话框会默认处理回车消息(即响应ONOK函数,然后关闭对话框),然后退出消息传递。
所以EDIT会收不到。
要解决这个问题,可以在EDIT窗口之前所有的对话框中重载PreTranslateMessage函数,然后在函数内加上:
if(pMsg->message==WM_KEYDOWN&&pMsg->wParam==VK_RETURN)//如果消息类型为WM_KEYDOWN并且用户按下的是回车
returnFALSE;//不翻译消息,直接将消息传递下去。
具体可查MSDN。
注意,这里返回值不能为TRUE,TRUE的意思是翻译消息后退出消息传递,如此一来虽然也能避开对话框默认处理,但是会退出消息传递,这样EDIT控件照样得不到消息。
如此,就可避开对话框默认处理,将消息传递下去。
注意:
只有对话框才会默认处理按下回车,CANCEL消息,其他控件窗口则不会,所以在其他窗口中不必重载PreTranslateMessage函数,当然如果重载了也不会错。
附:
关于PreTranslateMessage()函数的小程序示例:
BOOLCSearchuserDlg:
:
PreTranslateMessage(MSG*pMsg)
{
if(pMsg->message==WM_KEYDOWN)//判断是否有按键按下
{
switch(pMsg->wParam)
{
caseVK_DOWN:
//表示是方向键中的向下的键
//addhandlecodehere
break;
caseVK_UP:
//表示是方向键中的向上的键
//addhandlecodehere
break;
default:
break;
}
}
}
对话框里开一个线程,如果在线程还没结束时就强制退出,则会出现内存泄露。
关于读取版本问题:
1.GetModuleFileName函数可以获得当前运行程序的路径,PathRemoveFileSpec去掉路径名称的安装文件后的路径名称。
constintsize=256;
GetModuleFileName(NULL,str.GetBufferSetLength(size+1),size);
str.ReleaseBuffer();
2.获取当前运行程序的版本信息:
GetFileVersionInfoSize获得文件句柄,GetFileVersionInfo获得获得存放信息的数组大小,VerQueryValue获得版本的版本号信息,语言信息,
m_dwDataSize=0;
m_dwLangCharset=0;
m_pFixedFileInfo=NULL;
memset(m_cbInfoBuffer,0,sizeof(m_cbInfoBuffer));
//Openthefile
DWORDdwFileHandle=NULL;
DWORDdwBufferSize=:
:
GetFileVersionInfoSize((LPTSTR)lpszFileName,&dwFileHandle);
if((dwBufferSize==0)||(dwBufferSize>sizeof(m_cbInfoBuffer)))returnFALSE;
//theinformationoffile
m_dwDataSize=dwBufferSize;
if(:
:
GetFileVersionInfo(lpszFileName,dwFileHandle,sizeof(m_cbInfoBuffer),m_cbInfoBuffer)==FALSE)returnFALSE;
//theinformationoflanguage
UINTuQuerySize=0;
DWORD*pTransTable=NULL;
BOOLbSuccess=:
:
VerQueryValue(m_cbInfoBuffer,TEXT("\VarFileInfo\Translation"),(LPVOID*)&pTransTable,&uQuerySize);
if(bSuccess)m_dwLangCharset=MAKELONG(HIWORD(pTransTable[0]),LOWORD(pTransTable[0]));
//版本信息
if(:
:
VerQueryValue(m_cbInfoBuffer,TEXT("\\"),(void**)&m_pFixedFileInfo,&uQuerySize)==FALSE)returnfalse;
if((uQuerySize!
=sizeof(VS_FIXEDFILEINFO))||(m_pFixedFileInfo==NULL))returnfalse;
returntrue;
}
3.GetPrivateProfileString读取.ini文件中的字符串,GetPrivateProfileInt读取.ini中整型数据
GetPrivateProfileString("UPDATEDATA","DataUrl",NULL,s.GetBuffer(100),100,"..\\serverinfo.ini");
WritePrivateProfileString
参数表
lpApplicationName-String,要在其中写入新字串的小节名称。
这个字串不区分大小写。
lpKeyName------Any,要设置的项名或条目名。
这个字串不区分大小写。
用vbNullString可删除这个小节的所有设置项。
lpString-------String,指定为这个项写入的字串值。
用vbNullString表示删除这个项现有的字串。
lpFileName-----String,初始化文件的名字。
如果没有指定完整路径名,则windows会在windows目录查找文件。
如果文件没有找到,则函数会创建它。
编辑本段
函数在VC中的使用
在我们写的程序当中,总有一些配置信息需要保存下来,以便完成程序的功能,最简单的办法就是将这些信息写入INI文件中,程序初始化时再读入.具体应用如下:
一.将信息写入.INI文件中
1.所用的WINAPI函数原型为:
BOOLWritePrivateProfileString(
LPCTSTRlpAppName,
LPCTSTRlpKeyName,
LPCTSTRlpString,
LPCTSTRlpFileName
);
其中各参数的意义
LPCTSTRlpAppName是INI文件中的一个字段名.
LPCTSTRlpKeyName是lpAppName下的一个键名,通俗讲就是变量名.
LPCTSTRlpString是键值,也就是变量的值,不过必须为LPCTSTR型或CString型的.
LPCTSTRlpFileName是完整的INI文件名.
2.具体使用方法:
设现有一名学生,需把他的姓名和年龄写入c:
\stud\student.ini文件中.
CStringstrName,strTemp;
intnAge;
strName="张三";
nAge=12;
:
:
WritePrivateProfileString("StudentInfo","Name",strName,"c:
\\stud\\student.ini");
此时c:
\stud\student.ini文件中的内容如下:
[StudentInfo]
Name=张三
3.要将学生的年龄保存下来,只需将整型的值变为字符型即可:
strTemp.format("%d",nAge);
:
:
WritePrivateProfileString("StudentInfo","Age",strTemp,"c:
\\stud\\student.ini");
二.将信息从INI文件中读入程序中的变量
1.所用的WINAPI函数原型为:
DWORDGetPrivateProfileString(
LPCTSTRlpAppName,
LPCTSTRlpKeyName,
LPCTSTRlpDefault,
LPTSTRlpReturnedString,
DWORDnSize,
LPCTSTRlpFileName
);
其中各参数的意义
前二个参数与WritePrivateProfileString中的意义一样.
lpDefault:
如果INI文件中没有前两个参数指定的字段名或键名,则将此值赋给变量.
lpReturnedString:
接收INI文件中的值的CString对象,即目的缓存器.
nSize:
目的缓存器的大小.
lpFileName:
是完整的INI文件名.
2.具体使用方法:
现要将上一步中写入的学生的信息读入程序中.
CStringstrStudName;
intnStudAge;
GetPrivateProfileString("StudentInfo","Name","默认姓名",strStudName.GetBuffer(MAX_PATH),MAX_PATH,"c:
\\stud\\student.ini");
执行后strStudName的值为:
"张三",若前两个参数有误,其值为:
"默认姓名".
注意:
如果在读入的ini文件不存在,则按默认值生成相应的ini文件
3.读入整型值要用另一个WINAPI函数:
UINTGetPrivateProfileInt(
LPCTSTRlpAppName,
LPCTSTRlpKeyName,
INTnDefault,
LPCTSTRlpFileName
);
这里的参数意义与上相同.使用方法如下:
nStudAge=GetPrivateProfileInt("StudentInfo","Age",10,"c:
\\stud\\student.ini");
三.循环写入多个值,设现有一程序,要将最近使用的几个文件名保存下来,具体程序如下:
1.写入:
CStringstrTemp,strTempA;
inti;
intnCount=6;
文件:
//共有6个文件名需要保存
for(i=0;i{strTemp.format("%d",i);
strTempA=文件名;
文件:
//文件名可以从数组,列表框等处取得.
:
:
WritePrivateProfileString("UseFileName","FileName"+strTemp,strTempA,
"c:
\\usefile\\usefile.ini");
}
strTemp.format("%d",nCount);
:
:
WritePrivateProfileString("FileCount","Count",strTemp,"c:
\\usefile\\usefile.ini");
文件:
//将文件总数写入,以便读出.
2.读出:
nCount=:
:
GetPrivateProfileInt("FileCount","Count",0,"c:
\\usefile\\usefile.ini");
for(i=0;i{strTemp.format("%d",i);
strTemp="FileName"+strTemp;
:
:
GetPrivateProfileString("CurrentIni",strTemp,"default.fil",strTempA.GetBuffer(MAX_PATH),MAX_PATH,"c:
\\usefile\\usefile.ini");
文件:
//使用strTempA中的内容.
}
编辑本段
补充信息
补充四点:
1.INI文件的路径必须完整,文件名前面的各级目录必须存在,否则写入不成功,该函数返回FALSE值.
2.文件名的路径中必须为\\,因为在VC++中,\\才表示一个\.
3.也可将INI文件放在程序所在目录,此时lpFileName参数为:
".\\student.ini".
4.从网页中粘贴源代码时,最好先粘贴至记事本中,再往VC中粘贴,否则易造成编译错误,开始时我也十分不解,好好的代码怎么就不对呢?
后来才找到这个方法.还有一些代码中使用了全角字符如:
<,\等,也会造成编译错误
ShellExecute函数可以调用网站,安装文件等如
ShellExecute(AfxGetApp()->GetMainWnd()->m_hWnd,"open","..\\LEO.exe",NULL,NULL,SW_SHOWNORMAL);
在其他类中访问视图类的方法:
CMainFrame*pWnd=(CMainFrame*)AfxGetApp()->m_pMainWnd;
CCInetView*pView=(CCInetView*)pWnd->GetActiveView();获得视图指针,通过指针即可获得视图里的各种变量和成员函数.
TCHAR与Cstring的比较
在程序中,TCHAR与TCHAR之间是不可以直接判断是否是横等于的“==”,只有转换成Cstring类型的字符串才可以进行比较相等或者不相等等的情况。
同样,Cstring与TCHAR之间也是不可以直接比较的,必须进行转换成Cstring的字符串才可以进行比较判断,而他们之间的转换只需用到成员函数Format函数就可以实现。
Cstring有个成员函数GetBuffer(),如果用了此成员函数,想操作此字符串,必须用ReleaseBuffer()来释放
对数据初始化,memcpy
对结构体通常采用的是ZeroMemory这个函数进行初始化的,如ZeroMemory(&filehead,sizeof(filehead));其中filehead是结构体的实例。
memset就是将一个内存区全部设置成你指定的值。
以字节为单位。
ZeroMemory相当于memset(buffer,0,length)中参数2设置成0。
2.memset有个潜在的危险,它的后两个参数类型相同,但是含义大相径庭,如果不慎写反了编译时也不容易查出来;相比起源于Berkerly网络编程代码早期的bezro不是ANSIC函数,但它的两个参数更容易记忆。
在windows平台下,对于数组或纯结构使用ZeroMemory是安全的,对于类,则使用构造函数,不要调用ZeroMemory。
3.ZeroMemory是微软的SDK提供的,
memset属于CRun-timeLibrary,
所以ZeroMemory只能用于Windows系统,memset可用于别的系统。
ZeroMemory是一个宏,只是用于把一段内存的内容置零,内部是用memset实现的,memset可将内存置成别的字符。
如果你的程序是Win32程序而且不想连接c运行时库,那就用ZeroMemory,如果需要跨平台,那就用memset
memcpy可以对字符串进行安字节存入,读取,里面可以存进去结构体啥的
如:
charbuff[1024];//cmd,find均为结构体
memcpy(buff,&cmd,sizeof(cmd));
memcpy(&buff[sizeof(cmd)],&find,sizeof(find));
lstrcpyn也可以进行数据字符串的copy功能,但是有时候会丢失数据
//cun,m_TagInternet均为结构体
lstrcpyn(cun.GameName,m_TagInternet[m_DoCount].GameName,sizeof(cun.GameName));
ClistCtrl用法:
1.创建:
可以动态创建也可以在对话框内直接拉出来使用,如果想实现扩展的属性可以运用他的成员函数SetExtendedStyle来完成,LVS_EX_FULLROWSELECT是一下子可以选定一行LVS_EX_GRIDLINES使列表有网格的特征。
2.添加列,行。
添加列可以用成员函数InsertColumn来添加,而行必须用InsertItem来加入第一行的内容,然后再用SetItemText函数来完成行和列的加载工作如
for(inti=0;i { ZeroMemory(&userhead,sizeof(userhead)); userhead=m_user.GetAt(i); string.Format("%s",userhead.szAccounts); m_dataList->InsertItem(i,string); string.Format("%s",userhead.szNickName); m_dataList->SetItemText(i,1,string); } 3.加图象: 首先要CimageList来加载图片,然后再显示出来。 使菜单不可用 对于菜单,如果想控制他的可用与不可用必须先把m_bAutoMenuEnable设置成FALSE,否则不会其作用 控件绑定步骤: DDX_Control(ID,cwnd);一个控件ID,一个要关联的变量,这样就和一个类绑定起来了. DoDataExchange(CdataExchange*pDX);函数里实现控件对类的绑定。 他是个虚函数 按钮自绘: 按钮自绘的功能使用一个类如CmyButton从CButton里派生出来,用一个虚函数virtualvoidDrawItem(LPDRAWITEMSTRUCTlpDrawItemStruct)函数来实现绘制自己需要的按钮,在绘制过程中还可以根据位图形状进行绘制成位图形状的按钮。 A.鼠标操作 在派生类里可以实现鼠标移动到按钮,离开按钮,按下按钮等操作,WM_MOUSEMOVE,WM_LBUTTONDOWN,WM_LBUTTONDOANUP是MFC类里封装好的系统消息,但是WM_
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 日记 总结