博文

[置顶] 【更新】易懂的MFC入门教程(2008-11-28 09:15:00)

摘要:易懂的MFC入门教程  张孝祥--VC++讲义之 大 纲  第一课 Windows程序内部运行原理及SDK编程实现(一)    第一课 Windows程序内部运行原理及SDK编程实现(二)    第二课 C++经典知识回顾(一)   第二课 C++经典知识回顾(二)    第二课 C++经典知识回顾(三)    第三课:MFC思想   第四课:画线   第五课 文本    第六课:菜单(一)    第七课:菜单(二)   第八课:对话框(一)   第九课:对话框(二)   第十课:对话框之属性单    第十一课:Windows样式   第十二课: 对话框综合应用    第十三课:重绘    第十四课:文件和注册表读写   第十五课:文档系列化   第十六课:网络编程    第十七课:多线程   第十八课:动态链接库   第十九课:ActiveX控件    第二十课:勾子及数据库访问   附录:进程间通讯  
       ......

阅读全文(5391) | 评论:1

[置顶] Visual C++开发工具与调试技巧整理[转](2007-09-26 10:17:00)

摘要:Visual C++开发工具与调试技巧整理 自己总是用VC平台来开发东西,但是有时候总是出这样那样的问题,呵呵,总是需要上网查资料来解决,在这里把自己用到上网查的一些技巧摘录如下,希望对大家有用,省去大家再去搜索的烦恼。 1.如何在Release状态下进行调试 Project->Setting=>ProjectSetting对话框,选择Release状态。C/C++标签中的Category选General,Optimizations选Disable(Debug),Debut info选Program Database。在Link标签中选中Generate debug info复选框。   注:只是一个介乎Debug和Release的中间状态,所有的ASSERT、VERIFY都不起作用,函数调用方式已经是真正的调用,而不查表,但是这种状态下QuickWatch、调用队列跟踪功能仍然有效,和Debug版一样。 2. Release和Debug有什么不同 Release版称为发行版,Debug版称为调试版。 Debug中可以单步执行、跟踪等功能,但生成的可执行文件比较大,代码运行速度较慢。Release版运行速度较快,可执行文件较小,但在其编译条件下无法执行调试功能。 Release的exe文件链接的是标准的MFC DLL(Use MFC in a shared or static dll)。这些DLL在安装Windows的时候,已经配置,所以这些程序能够在没有安装Visual C++ 6.0的机器上运行。而Debug版本的exe链接了调试版本的MFC DLL文件,在没有安装Visual C++6.0的机器上不能运行,因为缺相应的DLL,除非选择use static dll when link。 3. ASSERT和VERIFY有什么区别 ASSERT里面的内容在Release版本中不编译,VERIFY里面的内容仍然翻译,但不再判断真假。所以后者更安全一点。 例如ASSERT(file.Open(strFileName))。 一旦到了Release版本中,这一行就忽略了,file根本就不Open()了,而且没有任何出错的信息。如果用VERIFY()就不会有这个问题。 4.Workspace和Project之间是什......

阅读全文(4997) | 评论:1

附录:进程间通讯(2007-09-26 19:06:00)

摘要:附录:进程间通讯 一、说明进程间通讯的必要性及困难性 二、Socket的方法,对于不同机器上且数据量很的情况会有很大的帮助,但对于同一台机器之间的不同进程之间的通讯就不方便了 (代码量太多) 三、进程间通讯的剪切板方法 a、对于发送端:        CString str;        GetDlgItemText(IDC_EDIT1,str);        HANDLE hGlobal;        if(this->OpenClipboard())//获取剪切板的资源所有权        {               EmptyClipboard();//将剪切板的内容清空               hGlobal=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);//在堆上分配一块用于存放数据的空间,程序返回一个内存句柄               char* pBuf=(char*)GlobalLock(hGlobal);//将内存块句柄转化成一个指针,并将相应的引用计数器加一               strcpy(pBuf,str.GetBuffer(str.GetLength()));//将字符串拷入指定的内存块中     ......

阅读全文(4828) | 评论:0

第二十课:勾子及数据库访问(2007-09-26 19:05:00)

摘要:第二十课:勾子及数据库访问 本讲主要内容: 第一部分:勾子 1、  回忆第一讲内容:(操作系统与应用程序的关系)由如果想从中间控制应用程序的消息,应该从哪入手?(如果把以高速公路上的汽车比作消息,以检查流串犯为例引出需要在检查站处设岗)从而引入勾子的概念,从而讲到勾子链(后挂的排在勾子链上的前面) 2、  函数的讲解(SetWindowsHookEx()与UnHookWindowHookEx())设一个勾子也只是调用一个API函数SetWindowsHookEx()函数,要想取消勾子的作用就要卸掉勾子,可以使用如下API函数UnhookWindowsHookEx()函数。(例子:在一个exe文件中实现一个简单的勾子,以处理回车键为例(VK_RETURN)) 2、在一个DLL文件中实现同上的一个简单的勾子(void setHook()、void UnHook()、setWindowsHookEx(WH_KEYBOARD,::GetModuleHandle(“HookDll”),GetCurrentThreadID())) 3、在一个DLL文件中实现一个系统级别的勾子(将线程号改为0)(此时可以用窃取别人密码为例子来讲) 3、  在一个EXE文件中实现一个自动启动全屏的应用程序并带一个DLL勾子 a、新建一个基于对话框的工程,去掉对话框类及相应的文件 b、从CWnd继承一个新类,实现其WM_PAINT消息响应函数 c、在InitInstance()中加入如下代码创建主窗口   CString ClassName=::AfxRegisterWndClass(0,0,(HBRUSH)::GetStockObject( WHITE_BRUSH),0);   m_FullWnd.Create(ClassName,"",WS_CHILD,CRect(0,0,0,0),CWnd::GetDesktopWindow(),1);   m_FullWnd.SetWindowPos(&CWnd::wndTopMost,0,0,::GetSystemMetrics(SM_CXSCREEN),::GetSystemMetrics(SM_CYSCREEN),SWP_SHOWWINDOW); &nbs......

阅读全文(4901) | 评论:1

第十九课:ActiveX控件(2007-09-26 19:04:00)

摘要:第十九课:ActiveX控件 本讲主要内容: 1、  首先认识什么叫ActiveX控件(VB演示MonthView控件与DatePicker控件) 演示一下在VB下的如何得到DTPicker下的日期内容及星期的内容,进而讲到属性,除了属性外还有方法和事件、属性页依次演示。 2、  VB中是很方便的,要是在VC中也能用就好了,开始在VC中演示如何使用ActiveX控件。同上一例子。(更进一步讲到属性、方法、事件的概念及容器与控件之间的关系等概念)演示如何得到日期的各个部分的内容。在此要讲到变体类型的变量(VARIANT结构及CComVariant类型及_variant_t类型的区别与联系) 3、  ActiveX控件中使用的技术分析,为了保证在各种开发工具上都能使用,对于在其内容实现时会有一些具体的要求。(字符串要使用(BSTR),颜色OLE_CORLOR,变体类型) 4、  注册与反注册(Regsvr32.exe工具的使用) 5、  创建一个ActiveX控件的方法,及常用工具的比较 6、  自动动手写一个时钟控件(工具介绍及常用选项说明及向导生成代码分析) 7、  修改图标 8、  在OnDraw中增加控件外观代码如下:(注意颜色转换的问题) CBrush br; br.CreateSolidBrush(TranslateColor(GetBackColor())); pdc->FillRect(rcBounds,&br); CTime tm=CTime::GetCurrentTime(); CString str=tm.Format("%H:%M:%S"); pdc->SetBkMode(TRANSPARENT); pdc->SetTextColor(TranslateColor(GetForeColor())); pdc->TextOut(0,0,str); 9、  解决不能自动更新的问题 a)         为控件响应WM_CREATE和WM_TIMER事件 b)    &nb......

阅读全文(4920) | 评论:1

第十八课:动态链接库(2007-09-26 19:03:00)

摘要:第十八课:动态链接库 一、概念: 1、  静态链接库: 应用程序从函数库中得到所的函数的执行代码,然后把招生代码自身的执行文件中,应用程序在运行时,不再需要函数库的支持。 2、  动态链接库: 应用程序的中不包含函数库中的函数的执行代码,编译和连接时只是包含包含它们的参考,运行时再将它们的执行代码加入内存,所以在程序运行时需要函数的支持。 二、编写DLL: 建立一个Windows Dynamic-Link Library,选择建一个An Empty Dll Project,加入一个CPP文件, int add(int x,int y) { return x+y; } extern "C" _declspec (dllexport) int add3(int x,int y,int z) {         return add(x,y)+z; } 说明: 1.  Add是一个供DLL中其它函数调用的函数, Add3是DLL提供给其它应用程序调用的函数。 2.  当DLL中含有输出函数时,编译DLL时会生成DLL文件和LIB文件。LIB文件称为DLL的导入库,它是一个特殊的库文件。它不包含执行代码,只是用来提供给链接器关于DLL函数在DLL中的入口信息,从而使得可执行程序 中也不会包含所调用DLL函数 的代码 ,只保留对DLL函数的动态链接参考。 3.  导出函数的两种方法: a.  使用微软专用的_declspec (dllexport):(如上面的例子) cpp文件在编译为OBJ文件时要对函数进行重新命名,C语言会把函数name重新命名为_name,而C++会重新命名为_name@@decoration, extern "C"表示用C语言的格式将函数重命名。 b.  使用模块定义文件: 模块定义文件即DEF文件,是包含一个或多个模块定义语句的文本文件,用来描述动态链接库的各种属性。 一个最小的·DEF文件包括以下模块定义语句: l         第一条语句必须是LIBRARY语句,用来说明动态......

阅读全文(4888) | 评论:0

第十七课:多线程(2007-09-26 19:02:00)

摘要:第十七课:多线程 一、概念: 进程:一个进程就是一个运行的程序,它有独立的内存、文件句柄和其他系统资源。当启动一个进程时,操作系统会为此进程建立一个4GB的地址空间,进程是操作系统分配内存地址空间的单位。 线程:是操作系统分配处理器时间的最基本单元。所以一个进程必须包含一个线程,我们称之为主线程。如果需要,进程可以产生更多的线程,让CPU在同一时间执行 不同段落的代码。 二、举例: 1.  在单线程中执行多个死循环: 建立一个控制台工程,加入一个cpp文件,编写如下代码: #include "stdio.h" void fun() {     while(1)     {         printf("thread 2 is rurnning!\n");     } } void main() {     fun();     while(1)     {         printf("thread 1 is running!\n");     } } 此时只能打出thread 2 is rurnning!,因为CPU总是在执行fun函数的代码 。没有机会向下执行其余代码。 2.  在单线程中执行多个死循环: #include "stdio.h" #include "windows.h" DWORD WINAPI fun(LPVOID lpParameter) {     while(1)     {         printf("thread 2 is rurnning!\n");     } } void main() { CreateThread(NULL,0,f......

阅读全文(5064) | 评论:0

第十六课:网络编程(2007-09-26 19:00:00)

摘要:第十六课:网络编程 一、UDP发送端: 建一个windows控制台工程,在main函数中加入: 1.  初始化DLL:          WSADATA wsaData;            WSAStartup(MAKEWORD(1,1),&wsaData);     Windows socket编程用到了微软提供的DLL,在使用前要对它进行初始化,Socket编程用到的DLL也分为不同的几个版本,WSAStartup函数的第一个参数就是用户所请求的版本号。 2.  生成socket:     SOCKET s= socket(AF_INET,SOCK_DGRAM,0); 3.  Bind:   SOCKADDR_IN sockSrc;        sockSrc.sin_family =AF_INET;        sockSrc.sin_port =htons(3000);        sockSrc.sin_addr .S_un .S_addr =htonl(INADDR_ANY);        bind (s,(SOCKADDR *)&sockSrc,sizeof(SOCKADDR)); 说明: a.bind函数要指定IP地址和端口号: IP地址:必须是执行这个程序所在计算机的IP地址,将其设定为INADDR_ANY,系统会自动将计算机的正确IP地址填入。 端口号:由于一台计算机可以启动多个网络程序,而IP地址只能保证网络数据到达指定的计算机,所以要指定端口号以区别数据是发给哪个网络程序。端口号是一个两个字节的整数,应把它设在1024到5000之间的值。若设为0,系统会将其设定为一个适当的数值。 B.由于各种计算......

阅读全文(4775) | 评论:0

第十五课:文档系列化(2007-09-25 15:51:00)

摘要:第十五课:文档系列化 一、在View中存取文件: 1.  用Carchive写文件:   CFileDialog dlg(false);     if (IDOK==dlg.DoModal())     {         CFile f(dlg.GetPathName(),CFile::modeCreate|CFile::modeWrite );         CArchive ar(&f,CArchive::store);         CString str("abc");         ar<<3<<'c'<<6.6f<<str;     } 2.  用Carchive读文件:     CFileDialog dlg(true);     if (IDOK==dlg.DoModal())     {         CFile f(dlg.GetPathName(),CFile::modeRead);         CArchive ar(&f,CArchive::load);           int x;         char c;         float d;    ......

阅读全文(5051) | 评论:0

第十四课:文件和注册表读写(2007-09-25 15:49:00)

摘要:第十四课:文件和注册表读写 一、文件操作: 1.  C的方式: FILE *p; p=fopen("c:\\1.txt","w"); fwrite("abc",1,4,p); fclose(p); 2.  C++的方式: ofstream f("c:\\1.txt"); f.write("hello",5); 3.  MFC的方式: I.                 写文件: CFile f("c:\\1.txt",CFile::modeWrite|CFile::modeCreate); f.Write("hello",5); a.几个标志的作用:   CFile::modeCreate:没有指定的文件就产生一个新文件,有就打开该文件,并将它裁剪到0;   CFile::modeNoTruncate :打开文件时不裁剪到0; b.写数据到文件末尾: CFile f("c:\\1.txt",CFile::modeWrite|CFile::modeCreate| CFile::modeNoTruncate);                     f.SeekToEnd(); f.Write("hello",5); II.              读文件: CFile f("c:\\1.txt",CFile::modeRead); char buf[10]; memset(buf,0,10); f.read(buf,5); MessageBox(buf); III.          文件对话框:   CFileDi......

阅读全文(5181) | 评论:0