博文
[置顶] 【更新】易懂的MFC入门教程(2008-11-28 09:15:00)
摘要:易懂的MFC入门教程
张孝祥--VC++讲义之 大 纲
第一课 Windows程序内部运行原理及SDK编程实现(一)
第一课 Windows程序内部运行原理及SDK编程实现(二)
第二课 C++经典知识回顾(一)
第二课 C++经典知识回顾(二)
第二课 C++经典知识回顾(三)
第三课:MFC思想
第四课:画线
第五课 文本
第六课:菜单(一)
第七课:菜单(二)
第八课:对话框(一)
第九课:对话框(二)
第十课:对话框之属性单
第十一课:Windows样式
第十二课: 对话框综合应用
第十三课:重绘
第十四课:文件和注册表读写
第十五课:文档系列化
第十六课:网络编程
第十七课:多线程
第十八课:动态链接库
第十九课:ActiveX控件
第二十课:勾子及数据库访问
附录:进程间通讯
......
[置顶] 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之间是什......
附录:进程间通讯(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()));//将字符串拷入指定的内存块中
 ......
第二十课:勾子及数据库访问(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......
第十九课: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......
第十八课:动态链接库(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语句,用来说明动态......
第十七课:多线程(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......
第十六课:网络编程(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.由于各种计算......
第十五课:文档系列化(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;
......
第十四课:文件和注册表读写(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......