C++程序设计

★程序员面试宝典
隐式类型转换的原则有:(优先级依次降低)1.当两个不同类型的值相运算时,会转化为长度更长的类型;2.浮点数和整型相运算,会转化成浮点类型;3.无符号整型和有符号整型相运算,会转化成无符号整型;
由于C++支持函数重载,所以C++编译后的函数名称会被编译器修饰;所以C++中调用C语言函数要指定extern "C"{ }来解决名字匹配问题。
防止头文件被重复引用应使用ifndef/define/endif宏。
在C中,const是一个不能被改变的普通变量,可以不用初始化,而且不是一个编译期间的常量,因此不能用作数组下标。(VC6.0下验证确实如此,这个改进恐怕就是C++更推荐用const代替宏来定义常量的原因)
结构体大小的计算方法:结构体中的每一个n字节的元素的首地址能被n整除,并且,最后结构体是以最大的n值对齐的。此外,空结构体的大小为1,虚继承的空结构体大小为4(有指向虚表的虚指针)。
当一个联合被说明时, 编译程序自动地产生一个变量, 其长度为联合中最大的变量长度。
数组作为参数传给函数时传的是指针而不是数组,所以即使参数写为a[n]形式也无法知道数组的大小,实际上这种形式等价于*a。
sizeof是一个操作符,可以用类型作参数(此时必须加括号),一般在编译期间可以计算出来,所以可以用作数组的下标。
类和结构是只有一个区别的:类的成员函数默认是private,而结构是public。但是,如果class或struct里面没有方法的话,它们是没有构造函数的,只能当作C语言中的struct使用。
需要传递动态内存必须使用**p参数或*(&p)。如果使用*p则因为形参是实参的copy,故只可以改变指针p所指向的内容(*p),而不能改变p本身的内容即p所指向的地址。
malloc与free是函数,而new/delete是运算符,后者可以保证对象在构建和销毁时执行构造函数或析构函数。


内存池是一种半自动内存管理方法,适用于操作可以分阶段的程序但不能和第三方库很好的合作.垃圾收集器通常会在当可用内存减少到少于一个具体的阈值时运行.通常,它们以程序所知的可用的一组"基本"数据,栈数据作为出发点,然后它们尝试去追踪通过这些数据连接到每一块数据.收集器找到的都是有用的数据,它没有找到的就是垃圾,可以被销毁并重新使用这些无用的数据.


CObject的析构函数是virtual型,则所有派生类的析构函数都将自动变为virtual型。这样当多态中父类指针撤销时会调用子类的析构函数,从而不会造成内存泄露。更一般的设计原则是:只要自己所设计的父基类中有虚函数,则该父基类的析构函数应该声明为virtual类型。
构造函数一般为公有类型,但以下两种情况也会设为私有类型:1.一个类只有一个实例的实现过程;2.定义友元,这样可以限制只有友元可以创建这个类的实例,其他类不能。这样的效果是只有友元可以控制这个类,如使用它的成员函数等。
当函数参数为引用传值或指针传值时,如果实参不为const修饰,则调用该函数时对应的形参不能传递const变量;如果实参使用const修饰,则形参传递常量或变量均可。当函数参数为普通传值时,则实参和形参之间没有关联和限制.
private修饰的属性或方法只能被该类的成员函数或友元函数访问;protected修饰的属性和方法只能被该类的成员函数和友元函数,以及派生类中的成员函数和友元函数访问。
私有继承就是把基类的公有成员和保护成员都作为派生类的私有成员;而保护继承是把基类的公有成员和保护成员都作为派生类的保护成员。
虚继承是为解决多重继承而出现的,可以对同样的祖父类只保留一份内存副本。一般在虚继承时会因为添加了指向父类的虚类指针而使大小增加4。


句柄是一个32位的无符号整数,实际上是Windows在内存中维护的一个对象(窗口等)内存物理地址列表的整数索引。对象的内存物理地址可能会改变(如系统自己进行内存整理),但对象所对应的句柄却一直会保持不变,且指向对象正确的内存物理地址。
C++同时提供了4种新的强制转化形式运算法:const_cast(expression)去掉const;dynamic_cast(expression);reinterpret_cast(expression);static_cast(expression)强制隐型
转换。
volatile是指一个对象的值可能会在编译器的控制或监测之外被改变。用来阻止编译器进行优化操作。
static有2个作用:函数体内,声明为静态的变量会在函数被调用的过程中保持不变;模块内(但在函数体外)的静态函数或变量是一个本地的全局变量,可以被这一模块内的其他函数调用或访问,但不能被模块外的函数调用或访问。






★C++编程实践
C++基础知识
#define用来定义替换。如果只是跟了一个标识符,而没有象征字符串,则会把源文件中的标识符全部移去,但该标识符仍然可以使用#if defined 和 #ifdef来检测到。 在这个语句中,使用反斜杠\来表示一个连续语句的换行。
C的字符串头文件是<string.h>,在C++里对应的头文件是<cstring>,string前面的c表示这个是c语言的;而C++的字符串头文件是<string>,是利用的模板实现的,跟原先C的实现方法不一样,但要安全得多。VC++中有<string.h>文件,它就是C中的那个;而<cstring>文件实际上只是在一个命名空间std中include了<string.h>,这是因为C++要减少名称污染;所以两个都是可以用的,但C++鼓励用<cstring>。还有,由于<iostream>和<iostream.h>文件都存在,但内容不同,所以要注意区分应该使用哪个头文件,比如要使用STL里的内容一般要使用C++的头文件<iostream>而不是C的头文件<iostream.h>。
main函数最标准的写法是:
int main(void) {……return 0;}
使用递归算法显然是一种低效率的做法.但使用栈的办法来消除递归并不会改变算法的效率,而且在VC6.0下实践发现:使用栈来消除递归的算法反而会耗费更长的时间.(这应该是由于函数调用时已经被编译器和系统优化的原因)


C++模板
声明模板的关键字为template <class T1,class T2,...>,简称为template关键字.template关键字只对分隔符间隔的下一个函数或类有效,如果有多个函数或类需要使用模板,则要分别在它们的前面加上template关键字.
函数模板直接使用函数名调用就可以,类模板需要先在类名后加上<t1,t2,...>实例化,其中t1,t2为具体的数据类型,然后实例化后的形式的整体可以像普通类一样使用:ClassName<t1,t2> ObjectName;
当类模板成员函数在类定义外实现时,它应该为一个函数模板的形式,即在每个成员函数前加上template关键字.类域的表示方法也要先将类模板实例化:ClassName<T>::,其中T需要与函数前template关键字中声明的类型相同,表示使用与template关键字所声明的相同的数据类型来实例化.


运算符重载
运算符重载的使用operator opt为函数名,opt必须为已有的运算符,与关键字operator之间有无空格均可.
调用该运算符重载函数时既可以使用operator opt(参数表)形式,也可以使用运算符运算形式,后者中运算符的优先级同系统运算符.
operator opt的参数个数必须与系统运算符opt对应,且参数表中至少有一个参数是用户自定义类型,例如:a++对应参数表为(mystruct a,int),++a对应参数表为(mystruct a).但内部操作任意,返回值也任意,不必与opt相同,比如+运算符可以返回值为空.
当运算操作符为类的成员函数时,第一个参数默认为类本身(*this).特别地,赋值运算符=必须在自定义结构中才能重载使用.
说明:1.函数返回类型为引用时,表示该函数可以作为左值使用,最简单的用途是把某个引用类型的参数返回,以供以后赋值修改(但这种用途较少见).更多的情况是,如果返回类型不是引用类型,就不可以做需要引用类型参数的函数的形参,所以,尤其对于运算符重载中,需要连加,连乘等操作且参数为引用类型的运算符重载函数,必须使用这种方法来实现.
2.函数可以使用类似fun(int,double)一样没有实参变量的参数表,表示调用格式同fun(int a,double b):fun(x,y),但是函数并不对形参x,y进行取值和处理.


C++流
C++流的根基类为ios,主要派生树为:ios -> istream,ostream -> iostream -> fstream,strstream.
ios类定义位于<ios.h>,iostream类定义位于<iostream.h>,fstream类定义位于<fstream.h>,strstream位于<strstrea.h>,而<iomanip.h>用于输入输出格式控制.头文件的关系为:<iostream.h>包含<ios.h>,而<iomanip.h>,<fstream.h>和<strstrea.h>都包含<iostream.h>.
ios类中定义了如下枚举变量:left,right,internal,dec,oct,hex,showbase,showpoint,uppercase,showpos,scientific,fixed.可用使用类成员函数setf()和unsetf()来设置和清除,其他有用的成员函数有:fill(),precision(),width(),eof()等.
<iomanip.h>还定义了可以直接放入<<,>>后进行使用的格式控制操纵符,与类ios成员函数的功能相对应的格式控制操纵符有:setiosflags(),resetiosflags(),setfill(),setprecision(),setw().此外,操纵符ws用来从输入流中去除空白字符,操纵符flush用来刷新一个输出流.
文件流fstream的主要函数有:
bool is_open() const;
void open(const char *s, ios_base::openmode mode = ios_base::in | ios_base::out); //同构造函数
void close();
字符串流strstream的主要函数有:
strstream(char *s, streamsize n, ios_base::openmode mode = ios_base::in | ios_base::out);
ostrstream(char *s, streamsize n, ios_base::openmode mode = ios_base::out); //输出的字符串缓冲空间需要给出空间大小
istrstream(const char *s, streamsize n); //输入的字符串缓冲空间可以没有大小限制
char* str(); //返回char*型字符串
streamsize pcount() const; //仅strstream和ostrstream有该成员函数,返回输出的字符串的大小
输入输出流iostream的主要函数有:(它的子类fstream,strstream都可以使用)
>>
int_type get();
basic_istream& get(E& c); //对应fstream,strstream类来说,E为char类型
basic_istream& getline(E *s, streamsize n, E delim); //delim为分隔符,不指定则为'\n'
int_type peek(); //读取一个元素却不移动流写指针
basic_istream& read(E *s, streamsize n);
basic_istream& putback(E c); //压回一个元素
pos_type tellg(); //返回流读指针位置
basic_istream& seekg(pos_type pos); //设置流读指针
basic_istream& seekg(off_type off, ios_base::seek_dir way); //使用相对坐标ios::beg, ios::cur, ios::end;
<<
basic_ostream& put(E c);
basic_ostream& write(E *s, streamsize n);
basic_ostream& flush(); //刷新输出流到输出目标
pos_type tellp(); //返回流写指针位置
basic_ostream& seekp(pos_type pos);
basic_ostream& seekp(off_type off, ios_base::seek_dir way);


API知识
GetSystemMetrics函数可以获得许多系统相关的参数,比如当前的屏幕分辨率。


MFC类知识
AfxMessageBox()就像控制台程序中的cout<<一样好用。
CString类型的Format函数输入有格式的字符串,很好用。
CDialog类最常用的一个函数是.DoModal(),显示对话框。
CFile类是MFC中用于文件操作.成员函数有Read,Write,Seek,GetLength,SetLength,GetFileName,GetFilePath,Rename,Remove等等.
CWnd类中封装了很多有用的API函数可以供绝大多数的控件使用(因为几乎所有可视控件都继承自它),比如:
//成员变量
m_hWnd //CWnd对象所关联的窗口的窗口句柄
//构造/析构函数
DestroyWindow() //销毁所关联的窗口
//初始化
Create(),CreateEx() //创建一个窗口并关联到CWnd对象
Attach(),Detach() //把一个窗口句柄关联/取消关联到CWnd对象
GetSafeHwnd() //返回m_hWnd指针
//窗口状态函数
EnableWindow() //允许或禁止鼠标键盘输入
GetActiveWindow(),SetActiveWindow() //获得/设置活动窗口
GetFocus(),SetFocus() //获取/设置有输入焦点的CWnd
//窗口大小和位置
IsIconic(),IsZoomed() //窗口是否是最小化/最大化
MoveWindow(),SetWindowPos() //改变窗口位置和顺序等,后者比前者复杂
GetWindowRect(),GetClientRect() //获得窗口的屏幕坐标/客户区坐标
//窗口存取函数
UpdateData() //设置或获得一个窗口的数据
//更新/绘制窗口
GetDC(),GetDCEx() //获得客户区显示设备上下文环境的句柄
GetWindowDC() //获得整个窗口的显示设备上下文环境的句柄
ReleaseDC() //释放客户区和整个窗口的显示设备上下文环境的句柄
UpdateWindow() //更新客户区
Invalidate() //使整个客户区无效
ShowWindow() //以指定方式来显示窗口,如最大化,最小化
//坐标映射函数
ClientToScreen(),ScreenToClient() //屏幕坐标和客户区坐标的相互转换
//窗口文本函数
SetWindowText(),GetWindowText() //设置/获取窗口文本或标题
GetWindowTextLength() //获得窗口文本或标题的长度
SetFont(),GetFont() //设置/获取所使用的字体
//滚动条功能
//拖拽功能
//插入字符光标功能
//对话框项目功能
GetDlgItemText(),SetDlgItemText() //获取/设置控件的标题或所关联的文字
//数据绑定函数
//菜单函数
SetMenu() //设置菜单项
//工具条函数
EnableToolTips(),CancelToolTips() //使能/禁止工具条
//计时器函数
SetTimer(),KillTimer() //开始/结束一个系统定时器
//警告功能
MessageBox() //弹出对话框
//窗口消息处理函数
SendMessage(),PostMessage(),SendNotifyMessage() //发送消息
//剪切板函数
//ActiveX控件
//初始化消息句柄,系统消息句柄,一般消息句柄,控件消息句柄,输入消息句柄,非客户区消息句柄,MDI消息句柄,剪切板消息句柄,菜单循环消息句柄
很多时候,查看MSDN某个类时,如果找不到要找的数据成员或函数成员时,就要继续向此类的父类中进行查找。
__int64类型是64位整数,可以进行加减乘除等运算,但不支持用标准输出函数如<<操作符来输出.需要10进制输出时需要使用位制转换的办法.


常用MFC函数
GetPrivateProfileString() //ini文件操作类


C++消息
ON_COMMAND 和ON_MESSAGE都是将消息处理函数加入消息路由表中。
ON_COMMAND对应的消息ID一直都是WM_COMMAND, 一般对应的是命令消息, 如菜单消息, 按钮消息等;
ON_MESSAGE的消息ID为ON_MESSAGE的第一个参数, 一般对应非命令消息, 如用户自定义消息。
对于用户的自定义消息, 一般使用#define WM_MYMESSAGE WM_USER+X来自定义名称, 其中X为数字。WM_USER一般提供给特定的控件定义自己的控件消息, 它被定义为0x0400。消息数字的意义如下:
0 - WM_USER – 1 Messages reserved for use by the system. 
WM_USER - 0x7FFF Integer messages for use by private window classes. 
WM_APP - 0xBFFF Messages available for use by applications. 
0xC000 - 0xFFFF String messages for use by applications. 
Greater than 0xFFFF Reserved by the system for future use. 
系统有两个方法将消息传递到窗口程序。Post系列函数会发送一个消息到先进先出的消息队列, 它把消息复制到消息队列, 消息循环最终捕获消息并分发到合适的窗口程序。Send系列函数会把消息直接发送到窗口程序, 绕过系统队列和线程消息队列。 
系统维护一个系统消息队列和每一个GUI线程的消息队列,为避免给non-GUI线程创建消息队列, 所有线程产生时并没有消息队列。仅当线程第一次调用GDI函数时, 系统给线程创建一个消息队列。
消息相关的函数有:
LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM IParam); //该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序, 直到窗口程序处理完消息再返回。
LRESULT CWindow::SendMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 ); //是ATL中的类函数。
LRESULT CWnd::SendMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 ); //是MFC中的类函数。
Control.sendMessage //是发消息给当前控件, send开头小写, 参数同前。
LRESULT SendMessageTimeout(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM IParam, UINTfuFlags, UIUT uTimeout, LPDWORD lpdwResultult); //该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序, 直到窗口程序处理完消息或指定的超时周期结束后再返回。
BOOL SendMessageCallback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM IParam, SEhDASYNCPROC IpResultCallBack, DWORD dwData); //该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序, 并立即返回。当窗口程序处理完消息后, 系统调用指定的回调函数, 将消息处理的结果和一个应用程序定义的值传给回调函数。
BOOL SendNotifyMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM IParam); //该函数将指定的消息发送到一个窗口。如果该窗口是由当前线程创建的;此函数为该窗口调用窗口程序, 并等待窗口程序处理完消息后再返回。如果该窗口是由不同的线程创建的, 此函数将消息传给该窗口程序, 并立即返回, 不等待窗口程序处理完消息。
BOOL CWindow::SendNotifyMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 ); //是ATL中的类函数。
BOOL CWnd::SendNotifyMessage( UINT message, WPARAM wParam, LPARAM lParam ); //是MFC中的类函数。
B00L PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); //该函数将一个消息放入(寄送)到与指定窗口创建的线程相联系消息队列里, 不等待线程处理消息就返回。
BOOL CWindow::PostMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 ); //是ATL中的类函数。
BOOL CWnd::PostMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 ); //是MFC中的类函数。
VOID PostQuitMessage(int nExitCode); //是Win32 API函数, 该函数寄送一个WM_QUIT消息给线程的消息队列并立即返回, 向系统表明有个线程有终止请求。通常用来响应WM_DESTROY消息。BOOL PostThreadMessage(DWORD idThread, UINT Msg, WPARAM wParam, LPARAM IParam);//该函数将一个消息放入(寄送)到指定线程的消息队列里, 不等待线程处理消息就返回。
BOOL CWinThread::PostThreadMessage( UINT message , WPARAM wParam, LPARAM lParam ); //是MFC中的类函数, CWinThread是CWinApp的父类。
BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax); //该函数从调用线程的消息队列里取得一个消息并将其放于指定的结构。此函数可取得与指定窗口联系的消息和由PostThreadMesssge寄送的线程消息。
BOOL PeekMessage(LPMSG IpMsg, HWND hWnd, UINT wMSGfilterMin, UINT wMsgFilterMax, UINT wRemoveMsg); //该函数为一个消息检查线程消息队列, 并将该消息(如果存在)放于指定的结构, 但不从消息队列中删除。


MFC中使用资源建立弹出式菜单
一、在资源编辑器中建立一个菜单资源。
二、在需要相应的地方建立类CMenu来实现弹出菜单。比如WM_CONTEXTMENU消息就是整个客户区的右键单击消息,在该消息的相应函数中可以插入CMenu代码来实现右键菜单。也可以加入按钮的单击事件函数中,这样左键单击按钮时也会弹出菜单。
三、CMenu类中所依次用到的函数:
BOOL CMenu::LoadMenu( UINT nIDResource ); //装载资源ID号所指定的菜单
CMenu* CMenu::GetSubMenu( int nPos ) const; //得到第nPos个子菜单的指针,nPos从0开始。
BOOL CMenu::TrackPopupMenu( UINT nFlags,int x,int y,CWnd* pWnd,LPCRECT lpRect = NULL ); //在指定位置弹出菜单,nFlags一般设置为TPM_LEFTALIGN (=0)
四、其他相关的类函数和API函数
BOOL GetCursorPos(LPPOlNT IpPoint); //该函数检取光标的位置,以屏幕坐标表示
BOOL SetCursorPos(int X, int Y); //该函数把光标移到屏幕的指定位置
BOOL ClipCursor(CONST RECT* lpRect); //该函数把光标限制在屏幕上的一个矩形区域内
BOOL GetClientRect(HWND hWnd, LPRECT lpRect); //该函数获取窗口客户区的坐标
void CWnd::GetClientRect( LPRECT lpRect ) const; //MFC类函数
BOOL GetWindowRect(HWND hWnd, LPRECTlpRect); //该函数返回指定窗口的边框矩形的尺寸,以屏幕坐标给出
void CWnd::GetWindowRect( LPRECT lpRect ) const; //MFC类函数
BOOL ClientToScreen(HWND hWnd,LPPOINT lpPoint); //该函数将指定点的用户坐标转换成屏幕坐标
void CWnd::ClientToScreen( LPPOINT lpPoint ) const; //MFC类函数
BOOL ScreenToClient(HWND hWnd, LPPOINT lpPoint); //该函数把屏幕坐标转换成用户坐标
void CWnd::ScreenToClient( LPPOINT lpPoint ) const; //MFC类函数


MFC中使用资源建立非弹出式菜单
一、在资源编辑器中建立一个菜单资源。
二、在窗口类的初始化函数中加入如下代码:
CMenu mymenu;
mymenu.LoadMenu(IDR_MENU);
this->SetMenu(&mymenu); //设置窗口的系统菜单为刚才载入的自定义的菜单资源
mymenu.Detach(); //将句柄分离,这样当变量mymenu离开作用域时窗口的系统菜单仍然不会消失
三、相关的类函数和API函数
CWnd* AfxGetMainWnd( ); //返回主窗口句柄(多文档、单文档返回CMainFrame指针,对话框返回CDialog指针),在非OLE server的程序中等同于直接引用CWnd变量CWinThread::m_pMainWnd
CWinApp* AfxGetApp( ); //返回指向该应用程序唯一的CWinApp对象的指针


MFC中不使用资源建立弹出式菜单和非弹出式菜单
一、如果建立弹出式菜单需要将CMenu *mymenu作为成员加入到窗口类中。在构造函数中使用new来生成对象,并动态建立菜单。在析构函数中加上销毁菜单的语句。在需要相应的函数中加入TrackPopupMenu()函数显示菜单。如果建立非弹出式菜单则只需在窗口类构造函数或初始化函数中动态建立菜单并加入系统菜单,因为mymenu是局部变量所以也不需要销毁菜单。特别地,如果建立的非弹出式菜单是下拉式的,需要把已经建好的下拉菜单加入到系统菜单,需要多个CMenu类对象。
二、动态建立和销毁菜单时CMenu类中所依次用到的函数:
BOOL CMenu::CreatePopupMenu( ); //创建一个弹出式菜单实例
BOOL CMenu::CreateMenu( ); //创建一个非弹出式菜单实例
BOOL CMenu::AppendMenu( UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL ); //把一个菜单项加入至菜单的末尾,该菜单项可以是CMenu::m_hMenu类型的下拉菜单
BOOL CMenu::DestroyMenu( ); //销毁菜单所占用的系统资源


MFC中显示位图
一、在客户区或屏幕显示的代码:
CDC* pDC = GetDC(); //获得客户区或整个屏幕的设备上下文环境,以用来在其上绘画
CBitmap bitmap; //生成CBitmap类对象
bitmap.LoadBitmap(IDB_MYPIC); //从资源载入位图的方法:IDB_MYPIC为位图资源的ID(先在资源管理器中“引入”所需的位图)
bitmap.Attach(LoadImage(NULL, "mypic.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)); //直接从硬盘载入位图的方法:mypic.bmp为需要载入的文件名
CDC memdc; //新建CDC类用来装载bitmap
memdc.CreateCompatibleDC(pDC); //创建与指定设备兼容的内存设备上下文环境
memdc.SelectObject(&bitmap); //把bitmap载入该内存设备的上下文环境
pDC->BitBlt(0,-20,1024,768,&memdc,0,0,SRCCOPY); //把位图从源内存设备拷贝到目标设备进行显示,1024*768是源和目标矩形区域的大小,(0,-20)是目标矩形区域左上角坐标,(0,0)是源矩形区域左上角坐标
ReleaseDC(pDC); //释放绘图资源
二、没有标题栏等,以整个图片为界面的方法:
1.在要显示的对话框的属性里选择样式为:无标题栏,无边框。
2.使用前一步的方法显示位图即可。
3.使用OnLButtonDown()来响应单击事件,并根据鼠标当时的位置来判断应该调用的函数,也可以不去直接调用函数而是发送对应的消息,再在自定义的消息响应函数中来处理。
4.如果界面上还有其他控件,则设置这些控件的位置需要首先生成控件变量,然后使用该控件变量的MoveWindow函数来设置控件的位置。
三、按钮显示图片
1.加入图像控件,在属性里选中"通知",就可以加入BN_CLICKED消息响应事件来处理鼠标单击时显示图片的动作了。
2.加入按钮控件,按钮的属性选中"位图",并生成它的控件变量m_mybtn,加入以下代码:
m_mybtn.SetBitmap(::LoadBitmap(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDB_MYPIC))); //IDB_MYPIC为资源ID
或者,需要在类中加入CBitmap类型的变量lbmp,然后再加入以下代码:
lbmp.LoadBitmap(IDB_MYPIC);
m_mybtn.SetBitmap(HBITMAP(lbmp));
四、相关类函数和API
退出程序用 AfxGetMainWnd()->SendMessage(WM_CLOSE); 
关闭当前窗口用 DestroyWindow(); 
关闭模式对话框用 EndDialog(0);









































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李小白杂货铺

打赏是一种友谊,让我们更亲密。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值