文档库 最新最全的文档下载
当前位置:文档库 › VC编程中注意的问题

VC编程中注意的问题

VC编程中注意的问题
VC编程中注意的问题

1、创建完整的Win32 Application的步骤:

2、windows应用程序的消息处理机制:

3、BeginPaint函数的使用注意:

4、注意:在C语言中结构体是不能有函数的,但是在C++中结构体是可以有函数的,被称为成员函数。在结构体中,默认的成员的“public”性质的,但是在类中默认的成员是“private”性质的,因此,对于公共成员变量或函数要声明“public”。

5、类的继承及类中成员的访问特性:(注意继承权限)

6、类的多重继承应该注意的顺序问题(不是太重要,但是对个别情况应当注意):

多重继承类的定义:

class B:public C,public D {…};

7、C++中类的多态性的实现:

编译器在编译的时候,如果发现基类中有virtual关键字,就会采用迟绑定(late binding)技术,这样就形成了类的多态性。

凡是含有纯虚函数的类,叫做抽象类,不能声明类对象,只能作为基类为派生类服务,在派生类中必须完全实现基类的纯虚函数,否则派生类也变成了抽象类,不能实例化对象。一般纯虚函数的定义如下:

virtual void breathe()=0;

注意:C++中类的多态性是由虚函数来实现的,而不是纯虚函数。在子类中如果有对基类的虚函数的覆盖定义,无论该覆盖定义是否有virtual关键字,都视为虚函数。

8、C++类中函数的覆盖及其与函数的隐藏之间的区别:

所谓隐藏,是指在派生类中具有与基类同名的函数,而不管其参数是否相同,从而在派生类中隐藏了基类中的函数。

函数覆盖与隐藏的区别:

当隐藏发生时,如果想在派生类的同名函数中调用基类的被隐藏函数,可以采用“基类名::函数名(参数)”语法形式进行调用。

9、在视图类中画图时,必须先获得设备描述表(DC),可以通过以下四种方式进行获取:

(1)利用全局函数的::GetDC(…)获取hDC,最后要利用::ReleaseDC(…)释放;

(2)利用CWnd类的GetDC()获取CDC的指针,最后要利用ReleaseDC()释放;

(3)利用CWnd类的CClientDC(…);(只作用于客户区)

(4)利用CWnd类的CWindowDC(…);(用法与CClientDC相同,随其参数取值的不同作用域就不同,可以作用于整个窗口,包括框架和视图窗口,比如this(客户区对象指针),GetParent(),GetDesktopWindow()分别作用于客户区,整个窗口,计算机桌面)

10、FillRect()和Rectangle()的区别:

11、一些应该掌握的函数:

GetStockObject():获取库存对象(画刷、画笔、调色板等)的句柄;

FromHandle():静态函数,将一个资源的句柄转化为该资源的对象指针;

SelectObject():将一种资源(画笔、画刷、字体等)选入设备描述表中;

SetROP2():设置图形显示模式;

CreateCaret():创建插入符;

SetCaretPos():设置插入符的位置;

LoadBitmap():加载图像;

CString::LoadString():加载一个由nID标识的资源;

GetTextMetrics():获取当前设备描述表的字体尺度信息;

GetTextExtent():获取一个字符串在屏幕上显示的宽度和高度;

Ellipse():绘画一个椭圆;

Rectangle():绘画一个矩形;

BeginPath():创建一个路径层(在路径层内进行的绘图操作,不影响原有的图形界面);EndPath():结束一个路径层;

SelectClipPath():主要用此函数设置一种模式,让路径层和剪裁区域进行互操作而达到一种特殊的效果(此函数以后的绘图操作都是在其选定的剪裁区域内进行的);CString::Left():截取字符串中左边一定长度的字符串作为新的字符串;

GetBkColor():获取背景色;

SetTextColor():设置文本颜色;

SetTimer():设置定时器,其参数为定时器标识,时间间隔和回调函数(一般设置为空);DrawText():将文本以一定格式(左输出或右输出等)输出在一个指定的矩形范围之内,可以实现卡拉OK机字幕变色显示效果。

12、响应菜单命令的顺序依次为:视图类、文档类、框架类、应用程序类。

13、Windows消息的分类及接受消息类的限制

14、一些应该掌握的函数:

CWnd::GetMenu():获取菜单栏对象的指针;

SetMenu():在窗口框架中加载或取消菜单栏;

CMenu::GetSubMenu():获取菜单栏的子菜单对象指针;

CheckMenuItem():设置或移除菜单项的标记;

SetDefaultItem():设置默认菜单(设置完成后菜单项的字体会被加粗,一个子

菜单只能有一个默认菜单项);

SetMenuItemBitmaps():设置菜单项的位图(可以设置选中和取消时显示不同

的位图);

EnableMenuItem():设置禁用或可用菜单项(禁用与变灰是不同的,禁用的菜

单不一定变灰,所以通常将禁用和变灰一起使用)LoadMenu():加载菜单;

TrackPopupMenu():显示一个弹出菜单;

AppendMenu():在(子)菜单(栏)尾部添加子菜单或菜单项;

InsertMenu():在(子)菜单(栏)指定位置处插入子菜单或菜单项;

DeleteMenu():删除菜单或菜单项;

DrawMenuBar():完成菜单栏的重绘操作(其调用者必须是菜单栏的拥有者,

否则不起作用);

GetActiveView():获取与当前框架关联的视图类对象的指针;

LOWORD:此宏从指定的32位值中取得低端字(低16位值);

HIWORD:此宏从指定的32位值中取得高端字(高16位值);

GetSystemMetrics():获取系统尺度信息(包括显示元素的宽度和高度以及系统配置信息);CWnd::GetClientRect():获取客户区矩形;

ClientToScreen():将客户区坐标转换为屏幕区坐标(视图类中的方法获取的点

坐标是相对于客户区,而不是屏幕区的);

15、使用EnableMenuItem()应该注意的一个问题:

16、非模式对话框对象变量范围的设置问题:

但对于模式对话框却没有这个限制,可以将模式对话框对象变量设置为局部变量。对于非模式对话框可以选择第一种情况比较简单,如果选择指针,还要在程序结束时销毁指针。17、非模式对话框中的OK按钮和模式对话框中的Cancel按钮,并不能真正的将对话框销毁,而是进行了隐藏,所以这两个按钮的动作方法需要重写。

18、应当掌握的一些函数:

CWnd::GetDlgItem():获取对话框上的某控件对象的指针(在对话框类中经常使用);

GetWindowText():获取窗口或控件的文本内容;

SetWindowText():设置窗口或控件的文本内容;

GetDlgItemText():获取对话框上的某控件的文本内容;

SetDlgItemText():设置对话框上的某控件的文本内容;

GetDlgItemInt():返回指定控件上的文本,并将其转换为整数;

SetDlgItemInt():设置指定控件上的文本(整型数值);

SetWindowPos():重新设置窗口的位置和大小(使窗口可大可小);

GetNextWindow():获取窗口的句柄,该函数返回与指定窗口有特定关系的窗口

句柄;

GetWindow():获取窗口的句柄,该函数返回与指定窗口有特定关系的窗口句柄;

GetNextDlgTabItem():此函数将获取指定控件前面或后面的一个具有

WS_TABSTOP风格的控件的句柄,按照Tab顺序查找控

件。

atoi():将一个数值字符串转化为相应的数值;

itoa():将一个数值转化为相应的字符串;

CPropertySheet:AddPage():向属性表单中添加属性页;

SetWizardMode():设置属性表单为向导模式;

SetWizardButtons():设置属性表单的向导按钮(上一步、下一步、完成

等)。

虚函数:OnSetActive():在属性页被激活时,该虚函数会被框架调用,可以重写此函数以

便在属性页中设置按钮的种类,利用SetWizardButtons()。

OnWizardNext():在属性页中点击“下一步”按钮时,应用程序框架就会调用此

虚函数,可以重写此函数以便对某些值进行检验。其值如果返

回-1则不能进入下一页。

OnWizardFinish():在属性页中点击“完成”按钮时,应用程序框架会调用此虚

函数,可以重写此虚函数以便保存属性页面所设置的内容。WM_INITDIALOG消息一般在窗口显示之前被调用,可以在此消息的响应函数中添加一些

窗口上的控件初始化的一些内容。

CListBox::AddString():向列表框中添加字符串;

CComboBox::SetCurSel():设置组合框的当前选项;

GetCurSel():获取组合框的当前选项;

GetLBText():获取组合框的列表框中的文本,可以与函数GetCurSel()

一起使用。

memset(Void* dest,int c,size_t count):将参数dest指定的内存空间的前count个字

节设置为字符:c。可以利用此函数对数组进行初始化。19、如何使静态文本发送通告信息呢?

20、一个编辑框如果没有选中multiline这一个属性,那么就不会支持多行输入,也就不能接收enter键按下的消息。

21、属性表单(CPropertySheet由属性页CPropertyPage组成)的创建步骤:

22、在利用单选按钮时,要为一组按钮的第一个单选按钮设置Group属性,这样这些单选按钮才能成为一组,直到遇到下一个(按照Tab顺序)具有Group属性的控件为止。23、属性表单被创建为向导时,其DoModal()的返回值就发生了变化,应当注意。

24、修改窗口的外观:

在窗口未创建之前,可以在虚函数PreCreateWindow()内进行相关的设置;如果在创建窗口之后进行设置,就要利用函数SetWindowLong()来进行相关内容的修改,不过利用此函数比较复杂。

25、在应用程序框架类中只能修改程序的图标,由于视图类对象覆盖于框架类对象之上,如果要改变应用程序窗口的背景色和光标,就要在视图类中实现。

26、应当掌握的一些函数:

AfxRegisterWndClass():可用于设置和修改应用程序窗口的样式、光标、背景和图标。要

将此函数放于虚函数PreCreateWindow()内,也是在窗口创建

之前修改的。

SetClassLong():可用于修改应用程序的样式、光标、图标和背景,不过是在窗口创建之

后进行的。

CToolBar::CreateEx():创建工具栏;

LoadToolBar():加载工具栏资源;

EnableDocking():设置此工具栏可以停靠在其他的窗口上;

CWnd::EnableDocking():设置此窗口可以被工具栏停靠;

DockControlBar():停靠指定的控件。

CFrameWnd::RecalcLayout():重新排布框架类对象上的控制条;

ShowControlBar():显示或隐藏控制条。

SetMessageText():直接在状态栏的第一个窗格内放置文本;

GetMessageBar():获取程序状态栏对象的指针;

CWnd::GetDescendantWindow():获取程序状态栏对象的指针;

CStatusBar::SetPaneText():设置状态栏上的文本;

CommandToIndex():将对应的指示ID转化为索引;

SetPaneInfo():可以为指定的窗格设置新的ID,样式和宽度。

GetItemRect():获取指定窗格的CRect对象,其中包含位置坐标(屏幕坐标)。CWnd::GetWindowRect():获取窗口的CRect对象(屏幕坐标);

GetClientRect():获取客户区的CRect对象(客户区坐标);

CWnd::MoveWindow():将窗口移动到指定的矩形范围内。

CProgressCtrl::SetPos():设置进度栏的位置;

SetRange():设置进度栏的范围;

SetStep():设置步长值;

StepIt():进度栏按照设定的步长值前进。

AfxGetInstanceHandle():获取当前程序的实例句柄;

AfxGetApp()—>m_hInstance:获取当前线程的实例句柄;

theApp. m_hInstance:获取当前线程的实例句柄,不过theApp的引用要注意下面的问题:

27、应当掌握的一些函数:

CDC::SetPixel():该函数在指定的点画一像素。

Rectangle():画一个矩形;

Ellipse():画一椭圆或圆;

28、CColorDialog类里面有一个CHOOSECOLOR结构体的成员变量:m_cc;

此结构体里面有两个常用的成员:rgbResult(代表颜色),Flags(初始标志,用法如下:)

CFontDialog类里面有一个CHOOSEFONT结构体的成员变量:m_cf;其中有一个常用的成员变量:lpLogFont,它指向一个LOGFONT结构体,其中包含字体的各种属性(包括字体的逻辑名称)。

29、窗口类对象与其相关联的窗口,二者之间有一个成员变量进行维系:m_hWnd,同样在CGdiObject类的对象和Window GDI资源之间也是有一个成员变量进行维系的,下面就进行详细的解说,如何将二者之间的关系解除?

对象,只是相对于类来说的。类对象生命周期结束,那么与其相关资源的生命周期也就结束,但反之则不一定成立。

30、一些应该掌握的一些函数:

CWnd::GetDlgCtrlID():获取对话框子控件的ID或者子窗口的ID。

CDC::SetTextColor():设置文本颜色—前景色;

SetBkMode(TRANSPARENT):设置背景色模式为透明(可以在设置文本颜色后使用)

SetBkColor():设置背景色;

CreateCompatibleDC():创建兼容dc;

BitBlt():将源设备中的设备上下文中的位图复制到目标设备上下文中(1:1复制);

StretchBlt():将源设备中的设备上下文中的位图复制到目标设备上下文中(可以实

现图像的伸缩);

CBitmap::GetBitmap():获取位图的大小尺寸等(其参数是BITMAP结构体);

集合类:

CStringArray:可以存储CString类的对象,其容量可以动态增加;

CObArray:可以存储CObject类对象的指针;

CPtrArray:可以存储void类型的指针,也就是说可以存储任何类的指针;CScrollView::SetScrollSizes():设置视窗文件的大小;

视窗类:虚函数OnInitialUpadate():是视窗类创建完成后调用的第一个函数,可以在这个

函数里面完成部分初始化工作(比方说设置视窗类初始大小尺寸等)。

虚函数OnPaint()中调用的虚函数OnPrepareDC():调整显示设备上下文属性;

能够变换视口的原点坐标;会随时根据滚动窗口的位置随时调整视

口的原点坐标。

CDC::DPtoLP():设备坐标点向逻辑坐标点转换;

LPtoDP():逻辑坐标向设备坐标点转换;

31、设备坐标和逻辑坐标的使用范围:

设备空间包括由视图类客户区和框架类空间等,因此,如果在一个设备空间内进行作图,得到的点的坐标是不能直接应用于另外设备空间的,这时也要进行相应的转换,比如:ScreenToClient(),ClientToScreen():完成屏幕与客户区的点坐标的相互转换。通常情况下,在窗口固定不变时(比方说没有滚动窗口),此时点的逻辑坐标和设备坐标位置是相同的。

32、逻辑坐标和设备坐标之间的转换:

33、利用元文件可以方便的进行对绘图的保存,元文件中存储的不是数据,而是绘图命令;CMetaFileDC::Create():创建一个元文件上下文与CMetaFileDC对象联系起来;

Close():关闭元文件上下文并获得元文件的句柄;

PlayMetaFile():播放元文件;

DeleteMetaFile():删除元文件(句柄);

CopyMetaFile():拷贝元文件到指定的文件;

GetMetaFile():从指定的文件获取元文件的句柄;

34、const char* 与char* const 的区别:

(1)const char*:

(2)char* const:

35、读写的同步和异步的含义:

36、一些应当掌握的一些函数:

WriteProfileString():将一个字符串添加到文件Win.ini(包括字段名,键,键值);

GetProfileString():从文件Win.ini中获取相关字段的信息;

RegCreateKey():创建指定的注册表项;

RegOpenKey():打开注册表的一个键;

RegSetValue():设置注册表相关的键值;

RegSetValueEx():设置注册表相关的键值(可以设置各种类型的键值);

RegQueryValue():获取注册表相关的键值;

RegQueryValueEx():获取注册表相关的键值(可以获取各种类型的键值);

37、串行化应当注意的问题:

38、在C++中“>>”表示提取,“<<”表示插入;

这两种符号一般用在Cout,Cin以及CArchive中,在进行提取操作时,对象提取的顺序必须与保存的顺序一致。

39、一些应当掌握的函数:

虚函数:OnNewDocument():是初始化文档的一部分(可以在此函数中添加一些初始化代码)。

CDocument::SetTitle():设置文档的标题;

CdocTemplate::GetDocString():可以用来获取IDR_MAINFRAME字符串资源中的各个

子串;

40、MFC中部分菜单命令的调用机制:

41、一个类可以通过以下五个步骤变成可串行化类:

具体的事例可以参考相关书籍;

42、可串行化类的内部实现机制:

43、如果要保存数据,实现文档的串行化,可以直接在文档类里增加变量,这样在视图类里面调用时,可以直接利用视图类的函数GetDocument()获取文档对象的指针;如果变量设在视图类里面,在文档类里面进行调用的话,就要获取视图类的对象,可以利用下面两个函数进行获取:CView::GetFirstViewPosition():获取第一个视图的位置,返回结构体POSITION对象;然后再利用CView::GetNextView(POSITION pos):获取视图类对象的指针,然后再调用相关的变量。

44、MFC的视图/文档结构的相关知识点(非常全面):

45、j++ 和++j的区别:

j++:先参与运算,再自加1;++j:先自加1,再参与运算;

46、new、delete的用法:

new:在堆上为对象建立内存空间;

delete:删除在堆上分配的内存空间。

在建立新的文档之前,要将以前保存的数据清空,可以在文档类的虚函数DeleteContents 中进行。

47、计算机的标识是通过IP地址完成的,但是网络程序的标识是通过端口号来完成的。

48、应用层、传输层、网络层使用的协议:

49、端口的概念及一些注意事项:

50、网络字节序:

51、利用套接字编程的步骤:

1、基于TCP的套接字编程:

2、基于UDP的套接字编程:

不过在有的应用软件内,既有客户端,又有服务器端,也就是说既要接收数据,又要发送数据,比如说QQ等网络聊天软件。

52、网络编程用到的一些函数:

基于TCP服务器端socket编程使用到的函数:

WSAStartUp():加载套接字库,并进行套接字库的版本协商。

WSACleanUp():清除套接字库,与WSAStartUp()配对使用。

MAKEWORD(x,y):该宏将x(高字节),y(低字节)转化为一个字(16比特位)。

LOBYTE():提取字的低字节转化为十进制数;

HIBYTE():提取字的高字节转化为十进制数;

socket(int af,int type,int protocol):创建套接字,其中第三个参数是与特定的地址家族相关的协议,如果设置为0,系统就会根据地址格式和套接字类别,自动选择一个合适的协议。htons():将一个短整型的数从主机字节顺序转换为TCP/IP网络字节顺序;

htonl():将一个长整型的数从主机字节顺序转换为TCP/IP网络字节顺序;

bind():绑定一个套接字和一个主机的IP地址;

listen():侦听套接字;

accept():等待接受来自客户端的请求;

send():向客户端发送数据;

recv():接受客户端发来的数据;

inet_ntoa():该函数接受一个in_addr结构体作为参数,返回一个点分十进制格式的IP地址;

inet_addr():该函数接受一个点分十进制格式的IP地址作为参数,返回一个适合分配给S_addr的u_long类型的值。

closesocket():关闭套接字;

在实际编写绑定函数的时候,应当设置的结构体SOCKADD_IN(在TCP/IP中代替SOCKADD)的值:

基于TCP客户端socket编程使用到的函数:

WSAStartUp():加载套接字库,并进行套接字库的版本协商。

WSACleanUp():清除套接字库,与WSAStartUp()配对使用。

MAKEWORD(x,y):该宏将x(高字节),y(低字节)转化为一个字(16比特位)。LOBYTE():提取字的低字节转化为十进制数;

HIBYTE():提取字的高字节转化为十进制数;

socket(int af,int type,int protocol):创建套接字,其中第三个参数是与特定的地址家族相关的协议,如果设置为0,系统就会根据地址格式和套接字类别,自动选择一个合适的协议。connect():向服务器发出连接请求;

recv():接收来自服务器的数据;

send():向服务器发送数据;

closesocket():关闭套接字;

WSACleanUp():终止套接字库的使用;

注意:IP地址127.0.0.1,是本地回路地址,无论机器上是否有网卡,都可以使用机器上的这个IP地址。如果编写的网络程序是在本地机器上运行的,就可以使用这个地址进行测试,如果是在两个计算机上运行的,就要设定服务器端所在计算机的IP地址。

基于UDP的客户端和服务器端的函数:

WSAStartUp():加载套接字库,并进行套接字库的版本协商。

WSACleanUp():清除套接字库,与WSAStartUp()配对使用。

MAKEWORD(x,y):该宏将x(高字节),y(低字节)转化为一个字(16比特位)。LOBYTE():提取字的低字节转化为十进制数;

HIBYTE():提取字的高字节转化为十进制数;

socket(int af,int type,int protocol):创建套接字,其中第三个参数是与特定的地址家族相关的协议,如果设置为0,系统就会根据地址格式和套接字类别,自动选择一个合适的协议。sendto():发送数据到服务器端;

bind():绑定一个套接字和一个主机的IP地址;

recvfrom():接收来自于客户端的数据;

closesocket():关闭套接字;

WSACleanUp():终止套接字库的使用;

gets():从标准输入流获取一行数据;

53、函数宏

带参数的宏也被称为"函数宏". 利用宏可以提高代码的运行效率: 子程序的调用需要压栈出栈, 这一过程如果过于频繁会耗费掉大量的CPU运算资源. 所以一些代码量小但运行频繁的代码如果采用带参数宏来实现会提高代码的运行效率。

e.g.

#define mul(x,y) ((x)*(y))

注意, 函数宏之后的参数要用括号括起来, 否则会产生宏的副作用,看看下面的例子:

e.g.

#define mul(x,y) x*y

"mul(1, 2+2);" 将被扩展为: 1*2 + 2

同样, 整个标记串也应该用括号引用起来:

e.g.

#define mul(x,y) (x)*(y)

sizeof mul(1,2.0) 将被扩展为sizeof 1 * 2.0

54、进程的含义:

55、一些应当掌握的函数:

CreateThread():创建线程(参数设置比较复杂);

sleep():使线程睡眠指定的一段时间。

CloseHandle():关闭对象句柄(并不是所以的都能关闭,具体见MSDN),创建完线程后,应将其返回的句柄马上关闭;

CreateMutex():创建互斥对象;

ReleaseMutex():释放互斥对象;

WaitForSingleObject():等待获取同步对象,可以是互斥对象、事件对象等;GetlastError():获取线程的最后错误代码,是建立在单个线程的基础之上的。

获取互斥对象的位置(要紧贴共享的对象)非常重要,在进行多线程的同步时,一定要小心谨慎。

互斥对象,谁拥有,谁释放——原则。

AfxSocketInit():加载套接字库;

CIPAddressCtrl::GetAddress():获取IP框内的地址;

CreateEvent():创建事件对象;

SetEvent():使事件对象处于有信号状态;

ResetEvent():使事件对象处于无信号状态;

InitializeCriticalSection():初始化关键代码段;

EnterCriticalSection():进入关键代码段,获取指定的临界区对象的所有权。该函数等待指定的临界区对象所有权,如果该所有权赋予了调用线程,则该函数就返回,否则该函数就会一直等待,从而导致线程等待(阻塞)。

LeaveCriticalSection():释放临界区对象的所有权;

DeleteCriticalSection():删除临界区对象;

56、在程序中,应当多加一些判断语句,用来判断某个函数是不是正确的执行,比方说,套接字的建立是否成功,绑定服务器上的套接字是否成功等,这些判断能够增强程序的操作安全性,所以在编写代码的时候应当注意。

57、如果要求使用完全面向对象的思想来编程,那么就不能采用全局函数和全局变量,如果有需要,可以将其声明为类的静态变量和静态函数,比如在创建新的线程的时候这么做。

58、在发送消息时,如果不需要传递参数,那么在进行消息的定义时,可以不带参数。

59、在在实现线程之间的同步时,不应当使用人工重置的事件对象,而应当使用自动重置的事件对象。

60、互斥对象、事件对象和关键代码用于同步时的区别:

61、基于消息的异步套接字的实现:

WSAStartup():加载套接字库;

WSASocket():创建异步套接字;

WSAsyncSelect():该函数为指定的套接字请求基于Windows消息的网络事件的通知,并自动将套接字设置为非阻塞模式;可以用在绑定函数之后。

WSARecvFrom():接收来自发送端的消息;

WSASendTo():向接收端发送数据;

gethostbyname():获取主机名,返回一个指向hostent数组的指针,主要用到其中的一个数据即获得IP地址:gethostbyname(…)->h_addr_list[0];

gethostbyaddr():将对方IP转化为域名;

62、用delete删除数组时,应当以格式“delete[] 数组名”进行。

63、读取发生网络事件的方法:

64、剪贴板的使用:

OpenClipBoard():打开剪贴板;

EmptyClipBoard():清空剪贴板,释放剪贴板上数据的句柄,并将剪贴板的拥有权给予当前打开剪贴板的窗口。

GlobalAlloc():分配全局内存,返回一个指向该进程中句柄表条目的指针;

GlobalLock():锁定全局内存对象,返回内存的地址;

GlobalUnlock():解锁;

SetClipBoardData():以指定的剪贴板格式向剪贴板上添加数据;

相关文档