VC++常用功能详解.docx
《VC++常用功能详解.docx》由会员分享,可在线阅读,更多相关《VC++常用功能详解.docx(13页珍藏版)》请在冰豆网上搜索。
VC++常用功能详解
常用功能代码目录
在View中如何得到Doc中的数据?
在Doc中如何通知相关的View更新显示?
在Doc中如何得到与它相关的视图Views?
怎样得到应用程序类?
怎样得到应用程序的主框架类Frame?
怎样在自定义类中得到当前视图View类?
怎样在框架类中得到当前文档Doc类?
怎样在自定义类中得到当前文档Doc类?
获取所有菜单项的数目。
设置菜单的风格。
SDI单文档状态栏编程
VC++头文件的包含顺序问题。
几种DC之间的区别
在绘图之前擦除屏幕
CSocket类网络通信编程步骤
为了显示和修改文档类的数据,在CView类中有一指向相应文档类对象的指针变量m_pDocument。
m_pDocument在CView中被说明为指向CDocument类的指针,而在具体的应用中文档类一般都是CDocument类的派生类,必须对m_pDocument指针进行强制类型转换才能利用它检索CDocument派生类的特有数据。
为此AppWizard在CView的派生类中专门生成了一成员函数GetDocument()来完成这一转换。
A、首先,使用下面的语句得到DOC的对象指针:
CC501WriterDoc*pDoc=GetDocument();
B、如果所用数据是DOC中的public类型的成员,则可直接访问如下:
pDoc->data;
但是按照C++的编程风格,一个类中的数据要尽量使用private型,同时给出两个访问的成员函数Get()和Set()。
这样得到数据就要用如下形式:
CStringtext=pDoc->GetData();
在CDocument的派生类中调用以下语句:
UpdateAllViews();
在CDocument的派生类中,要得到与它相关的用于显示的视图可调用以下语句:
POSITIONpos=GetFirstViewPosition();//取得第一个视图
CC501WriterView*pv=(CC501WriterView*)GetNextView(pos);//下一个视图
在任何地方可使用以下形式得到:
CC501WriterApp*pApp=(CC501WriterApp*)AfxGetApp();
或者直接使用全局变量theApp。
MFC为我们提供了一个全局函数AfxGetInstanceHandle(),可以用来获取当前应用程序的实例句柄。
CMainFrame*pFrm=(CMainFrame*)AfxGetMainWnd();
或者CMainFrame*pFrm=(CMainFrame*)AfxGetApp()->m_pMainWnd;
如果当前类是在App中,则还可以用以下方法得到:
CMainFrame*pFrm=(CMainFrame*)m_pMainWnd;
或者CMainFrame*pFrm=(CMainFrame*)GetMainWnd;
程序中往往有程序员自已增加的类,例如用户生成的一个对话框类。
在这些自定义类中要得到当前的视图View类时,可以使用以下方法:
CMainFame*pFrm=(CMainFame*)AfxGetMainWnd();
CC501WriterView*pv=(CC501WriterView*)pFrm->GetActiveView();
CSDISplitterDoc*pDoc=(CSDISplitterDoc*)GetActiveDocument();
在自定义类中要得到当前的文档DOC类时,可以按标题五的步骤做,然后:
CC501WriterDoc*pDoc=(CC501WriterDoc*)pv->GetDocument();
或者:
CC501WriterDoc*pDoc=(CC501WriterDoc*)pFrm->GetActiveDocument();
A、以CMenu类为基类派生一个CCustomMenu类,CCustomMenu类常用于菜单的绘制。
B、在CCustomMenu类的头文件中声明变量或函数,代码如下:
staticintGetAllItemCount(HMENUhMenu,int&ItemCount,BOOLFirstFind=TRUE);
intm_ItemCount;
intAttatchMenu(HMENUhMenu);
C、添加AttatchMenu方法,该方法将当前窗口的菜单与自定义的菜单关联,代码如下:
intCCustomMenu:
:
AttatchMenu(HMENUhMenu)
{
Attach(hMenu);
intcount=GetAllItemCount(hMenu,m_ItemCount);
returncount;
}
D、添加静态GetAllItemCount方法,该方法用于得到所有菜单项的数目,代码如下:
GetAllItemCount(HMENUhMenu,int&ItemCount,BOOLFirstFind)
CMenu*pMenu=CMenu:
FromHandle(hMenu);//获得菜单的句柄
if(pMenu)
if(FirstFind)
ItemCount=0;
intcount=pMenu->GetMenuItemCount();
ItemCount+=count;
CMenu*pSubMenu=NULL;
for(inti=0;i{pSubMenu=pMenu->GetSubMenu(i);if(pSubMenu!=NULL){GetAllItemCount(pSubMenu->m_hMenu,ItemCount,FALSE);}}}returnItemCount;}E、然后在框架类或对话框类的OnCreate()函数或OnInitDialog()函数中调用AttatchMenu函数,代码如下:HMENUhMenu=GetMenu()->GetSafeHmenu();if(hMenu!=NULL){//CCustomMenum_Menu;intcount=m_Menu.AttatchMenu(hMenu);}设置菜单的风格。A、以CMenu类为基类派生一个CCustomMenu类,CCustomMenu类常用于菜单的绘制。B、在CCustomMenu类的头文件中定义一个CMenuItem结构体,代码如下:structCMenuItem{CStringm_MenuText;//菜单项的文本UINTm_ImageIndex;//菜单项图像索引intm_MenuType;//菜单项的类型,-2顶层菜单,-1弹出式菜单,0分隔条,其他普通菜单};C、在CCustomMenu类的头文件中声明变量或函数,代码如下:BOOLSetMenuItemInfo(CMenu*pMenu,BOOLToped=TRUE);intm_ItemCount;intm_Index;//遍历菜单时使用的索引CMenuItem*m_MenuList;intAttatchMenu(HMENUhMenu);D、添加AttatchMenu方法,该方法将当前窗口的菜单与自定义的菜单关联,代码如下:intCCustomMenu::AttatchMenu(HMENUhMenu){Attach(hMenu);intcount=GetAllItemCount(hMenu,m_ItemCount);if(m_ItemCount>0)m_MenuList=newCMenuItem[m_ItemCount];returncount;}E、添加SetMenuItemInfo方法,该方法用于设置菜单风格,代码如下:BOOLCCustomMenu::SetMenuItemInfo(CMenu*pMenu,BOOLToped){if(pMenu!=NULL){intMenuCount=pMenu->GetMenuItemCount();for(inti=0;i{//获得菜单文本pMenu->GetMenuString(i,m_MenuList[m_Index].m_MenuText,MF_BYPOSITION);UINTMenuID=pMenu->GetMenuItemID(i);//获得菜单ID//MenuID=-1,Toped=FALSE;表示弹出式菜单if((MenuID=-1||MenuID==65535)&&Toped==TRUE){MenuID=-2;}m_MenuList[m_Index].m_MenuType=MenuID;//设置菜单列表//修改菜单风格pMenu->ModifyMenu(i,MF_OWNERDRAW|MF_BYPOSITION|MF_STRING,m_MenuList[m_Index].m_MenuType,(LPSTR)&(m_MenuList[m_Index]));m_Index+=1;CMenu*pSubMenu=pMenu->GetSubMenu(i);//获得子菜单句柄if(pSubMenu){SetMenuItemInfo(pSubMenu,FALSE);//递归调用SetMenuItemInfo}}}returnTRUE;}F、然后在框架类或对话框类的OnCreate()函数或OnInitDialog()函数中调用SetMenuItemInfo函数,代码如下:HMENUhMenu=GetMenu()->GetSafeHmenu();if(hMenu!=NULL){//CCustomMenum_Menu;intcount=m_Menu.AttatchMenu(hMenu);m_Menu.SetMenuItemInfo(&m_Menu);//设置菜单项}SDI单文档状态栏编程A、自定义状态栏指示器。在资源的StringTable中添加:IDS_STATE颜色在MainFram.cpp中添加IDS_STATEstaticUINTindicators[]={ID_SEPARATOR,//statuslineindicatorIDS_STATE,//添加的内容ID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,};B、在MainFrm.h中修改:public:CStatusBarm_wndStatusBar;//默认为私有,这里改为公有C、在CmyTestView.cpp中加入#include“MainFrm.h”D、在视类中的消息响应函数中添加:CSizesz=dc.GetTextExtent(str);CMainFrame*pFrame=(CMainFrame*)AfxGetMainWnd();pFrame->m_wndStatusBar.SetPaneInfo(1,IDS_STATE,SBPS_NORMAL,sz.cx);pFrame->m_wndStatusBar.SetPaneText(1,str);VC++头文件的包含顺序问题。如果顺序不对会有以下错误:errorC2143:syntaxerror:missing';'before'*'errorC2501:'CMyTestView':missingstorage-classortypespecifierserrorC2501:'pv':missingstorage-classortypespecifiers在任何cpp文件的开头都应该以这样的顺序:#include"MyTestDoc.h"#include"MyTestView.h"#include"MainFrm.h"注意,Doc的头文件一定要在最前面。这样你的CDemoView和CMyView也可以共享一个CDemoDoc。一般在Cpp中包含文件是要注意类的包含关系,被包含的类定义应该在前面。如果实在有冲突,可以在一个类的头文件中加:classCXXXDoc;之类的空定义。这样定义过的头文件中可以用CXXXDoc申明指针,但是不能申明实际对象。几种DC之间的区别CDC及其派生类的继承视图:Cobjectpublic|------CDCpublic|------|------CClientDCpublic|------|------CpaintDCpublic|------|------CwindowDCpublic|------|------CMetaFileDCCClientDC:(客户区设备上下文)用于客户区的输出,与特定窗口关联,可以让开发者访问目标窗口中客户区,其构造函数中包含了GetDC,析构函数中包含了ReleaseDC:用法是:CClientDCdc(this);//this一般指向本窗口或当前活动视图dc.TextOut(10,10,str,str.GetLength());//利用dc输出文本,如果是在CScrollView中使用,还要注意调用OnPrepareDC(&dc)调整设备上下文的坐标。CPaintDC用于响应窗口重绘消息(WM_PAINT)是的绘图输出。CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中调用EndPaint()释放设备上下文。EndPaint()除了释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。CPaintDC也只能用在WM_PAINT消息处理之中。CPaintDC::CPaintDC(CWnd*pWnd){...if(!Attach(::BeginPaint(m_hWnd=pWnd->m_hWnd,&m_ps)))AfxThrowResourceException();}CPaintDC::~CPaintDC(){...::EndPaint(m_hWnd,&m_ps);Detach();}CWindowDC:关联一特定窗口,允许开发者在目标窗口的任何一部分进行绘图,包含边界与标题,这种DC同WM_NCPAINT消息一起发送CWindowDC与CClientDC,CPaintDC的区别:CWindowDC可在非客户区绘制图形,而CClientDC,CPaintDC只能在客户区绘制图形。CWindowDC下坐标原点是在屏幕的左上角,CClientDC,CPaintDC下坐标原点是在客户区的左上角。//CWindowDCdc(this);//this代表只能在view区域绘画//CWindowDCdc(GetParent());//在整个frame区域绘画CWindowDCdc(GetDesktopWindow());//可在整个桌面区域绘画dc.MoveTo(m_ptOrigin);dc.LineTo(point);CClientDC与CPaintDC的区别:CPaintDC的对象一般用在OnPaint内以响应Windows消息WM_PAINT,自动完成绘制,在整个窗口内进行重画,维持原有窗口完整性。CClientDC应用在非响应Windows消息WM_PAINT的情况下,进行实时绘制,绘制的区域内被重画。另外CDC和HDC都要手动释放。HDChDC;hDC=::GetDC(m_hWnd);MoveToEx(hDC,m_ptOrigin.x,m_ptOrigin.y,NULL);LineTo(hDC,point.x,point.y);::ReleaseDC(m_hWnd,hDC);CDC*pDC=GetDC();pDC->MoveTo(m_ptOrigin);pDC->LineTo(point);ReleaseDC(pDC);方法一:此方法在设备结束时不会销毁原来的资源(即:hDC,hBitmap)CDC*pDC=CDC::FromHandle(hDC);方法二:此方法在设备结束时会销毁原来的资源(即:hDC,hBitmap)CDCdc;dc.Attach(hDC);在绘图之前擦除屏幕CClientDCdc(this);RECTrc;GetClientRect(&rc);PatBlt(dc,rc.left,rc.top,rc.right,rc.bottom,WHITENESS);//刷上白色CSocket类网络通信编程步骤1.构造CSocket对象,如以下的形式:CSocketServersocket;2.利用CSocket对象的Create()函数创建WindowsSocket,Create()函数会调用Bind()函数将此Socket绑定到指定的地址上,其原型为:BOOLCreate(UINTnSocketPort=0,intnSocketType=SOCK_STREAM,LPCTSTRlpszSocketAddress=NULL);其中nSocketPort参数指定通信连接的端口号,端口号可以任意指定,但最好不要使用系统默认的一些端口号,例如21是FTP文件传输使用的端口号;3.Socket创建完毕之后,在服务器端进行监听客户的连接请求,使用如下的代码:ServerSocket.Listen();紧接着对于客户端而言,将会调用Connect()函数向服务器发送连接请求,而对于服务器而言,则会调用Accept()函数对客户端发送过来的请求连接进行接受和处理,Accept()函数可以创建一个和监听Socket相同的连接Socket来处理客户的请求,二原来的Socket仍然处于监听状态,使用的形式如下。客户端:ClientSocket.Connect(服务器的地址,服务器的端口号);服务器端:CSocketReceiveSocket;ServerSocket.Accept(连接Socket,客户的地址结构,客户地址结构的长度)4.对于数据流服务器类型而言,服务器和客户各自通过调用函数来完成数据的发送和接受,使用如下的语句:ServerReceive.Receive(缓冲区,缓冲区的长度,接受标志位);Client.Send(缓冲区,缓冲区的长度,发送标志位);5.在客户端与服务器端的数据传输完成之后,调用下述语句,释放Socket所占有的资源。ServerSocket.Close();ReceiveSocket.Close();ClientSocket.Close();
pSubMenu=pMenu->GetSubMenu(i);
if(pSubMenu!
=NULL)
GetAllItemCount(pSubMenu->m_hMenu,ItemCount,FALSE);
returnItemCount;
E、然后在框架类或对话框类的OnCreate()函数或OnInitDialog()函数中调用AttatchMenu函数,代码如下:
HMENUhMenu=GetMenu()->GetSafeHmenu();
if(hMenu!
//CCustomMenum_Menu;
intcount=m_Menu.AttatchMenu(hMenu);
B、在CCustomMenu类的头文件中定义一个CMenuItem结构体,代码如下:
structCMenuItem
CStringm_MenuText;//菜单项的文本
UINTm_ImageIndex;//菜单项图像索引
intm_MenuType;//菜单项的类型,-2顶层菜单,-1弹出式菜单,0分隔条,其他普通菜单
};
C、在CCustomMenu类的头文件中声明变量或函数,代码如下:
BOOLSetMenuItemInfo(CMenu*pMenu,BOOLToped=TRUE);
intm_Index;//遍历菜单时使用的索引
CMenuItem*m_MenuList;
D、添加AttatchMenu方法,该方法将当前窗口的菜单与自定义的菜单关联,代码如下:
if(m_ItemCount>0)
m_MenuList=newCMenuItem[m_ItemCount];
E、添加SetMenuItemInfo方法,该方法用于设置菜单风格,代码如下:
BOOLCCustomMenu:
SetMenuItemInfo(CMenu*pMenu,BOOLToped)
if(pMenu!
intMenuCount=pMenu->GetMenuItemCount();
for(inti=0;i{//获得菜单文本pMenu->GetMenuString(i,m_MenuList[m_Index].m_MenuText,MF_BYPOSITION);UINTMenuID=pMenu->GetMenuItemID(i);//获得菜单ID//MenuID=-1,Toped=FALSE;表示弹出式菜单if((MenuID=-1||MenuID==65535)&&Toped==TRUE){MenuID=-2;}m_MenuList[m_Index].m_MenuType=MenuID;//设置菜单列表//修改菜单风格pMenu->ModifyMenu(i,MF_OWNERDRAW|MF_BYPOSITION|MF_STRING,m_MenuList[m_Index].m_MenuType,(LPSTR)&(m_MenuList[m_Index]));m_Index+=1;CMenu*pSubMenu=pMenu->GetSubMenu(i);//获得子菜单句柄if(pSubMenu){SetMenuItemInfo(pSubMenu,FALSE);//递归调用SetMenuItemInfo}}}returnTRUE;}F、然后在框架类或对话框类的OnCreate()函数或OnInitDialog()函数中调用SetMenuItemInfo函数,代码如下:HMENUhMenu=GetMenu()->GetSafeHmenu();if(hMenu!=NULL){//CCustomMenum_Menu;intcount=m_Menu.AttatchMenu(hMenu);m_Menu.SetMenuItemInfo(&m_Menu);//设置菜单项}SDI单文档状态栏编程A、自定义状态栏指示器。在资源的StringTable中添加:IDS_STATE颜色在MainFram.cpp中添加IDS_STATEstaticUINTindicators[]={ID_SEPARATOR,//statuslineindicatorIDS_STATE,//添加的内容ID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,};B、在MainFrm.h中修改:public:CStatusBarm_wndStatusBar;//默认为私有,这里改为公有C、在CmyTestView.cpp中加入#include“MainFrm.h”D、在视类中的消息响应函数中添加:CSizesz=dc.GetTextExtent(str);CMainFrame*pFrame=(CMainFrame*)AfxGetMainWnd();pFrame->m_wndStatusBar.SetPaneInfo(1,IDS_STATE,SBPS_NORMAL,sz.cx);pFrame->m_wndStatusBar.SetPaneText(1,str);VC++头文件的包含顺序问题。如果顺序不对会有以下错误:errorC2143:syntaxerror:missing';'before'*'errorC2501:'CMyTestView':missingstorage-classortypespecifierserrorC2501:'pv':missingstorage-classortypespecifiers在任何cpp文件的开头都应该以这样的顺序:#include"MyTestDoc.h"#include"MyTestView.h"#include"MainFrm.h"注意,Doc的头文件一定要在最前面。这样你的CDemoView和CMyView也可以共享一个CDemoDoc。一般在Cpp中包含文件是要注意类的包含关系,被包含的类定义应该在前面。如果实在有冲突,可以在一个类的头文件中加:classCXXXDoc;之类的空定义。这样定义过的头文件中可以用CXXXDoc申明指针,但是不能申明实际对象。几种DC之间的区别CDC及其派生类的继承视图:Cobjectpublic|------CDCpublic|------|------CClientDCpublic|------|------CpaintDCpublic|------|------CwindowDCpublic|------|------CMetaFileDCCClientDC:(客户区设备上下文)用于客户区的输出,与特定窗口关联,可以让开发者访问目标窗口中客户区,其构造函数中包含了GetDC,析构函数中包含了ReleaseDC:用法是:CClientDCdc(this);//this一般指向本窗口或当前活动视图dc.TextOut(10,10,str,str.GetLength());//利用dc输出文本,如果是在CScrollView中使用,还要注意调用OnPrepareDC(&dc)调整设备上下文的坐标。CPaintDC用于响应窗口重绘消息(WM_PAINT)是的绘图输出。CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中调用EndPaint()释放设备上下文。EndPaint()除了释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。CPaintDC也只能用在WM_PAINT消息处理之中。CPaintDC::CPaintDC(CWnd*pWnd){...if(!Attach(::BeginPaint(m_hWnd=pWnd->m_hWnd,&m_ps)))AfxThrowResourceException();}CPaintDC::~CPaintDC(){...::EndPaint(m_hWnd,&m_ps);Detach();}CWindowDC:关联一特定窗口,允许开发者在目标窗口的任何一部分进行绘图,包含边界与标题,这种DC同WM_NCPAINT消息一起发送CWindowDC与CClientDC,CPaintDC的区别:CWindowDC可在非客户区绘制图形,而CClientDC,CPaintDC只能在客户区绘制图形。CWindowDC下坐标原点是在屏幕的左上角,CClientDC,CPaintDC下坐标原点是在客户区的左上角。//CWindowDCdc(this);//this代表只能在view区域绘画//CWindowDCdc(GetParent());//在整个frame区域绘画CWindowDCdc(GetDesktopWindow());//可在整个桌面区域绘画dc.MoveTo(m_ptOrigin);dc.LineTo(point);CClientDC与CPaintDC的区别:CPaintDC的对象一般用在OnPaint内以响应Windows消息WM_PAINT,自动完成绘制,在整个窗口内进行重画,维持原有窗口完整性。CClientDC应用在非响应Windows消息WM_PAINT的情况下,进行实时绘制,绘制的区域内被重画。另外CDC和HDC都要手动释放。HDChDC;hDC=::GetDC(m_hWnd);MoveToEx(hDC,m_ptOrigin.x,m_ptOrigin.y,NULL);LineTo(hDC,point.x,point.y);::ReleaseDC(m_hWnd,hDC);CDC*pDC=GetDC();pDC->MoveTo(m_ptOrigin);pDC->LineTo(point);ReleaseDC(pDC);方法一:此方法在设备结束时不会销毁原来的资源(即:hDC,hBitmap)CDC*pDC=CDC::FromHandle(hDC);方法二:此方法在设备结束时会销毁原来的资源(即:hDC,hBitmap)CDCdc;dc.Attach(hDC);在绘图之前擦除屏幕CClientDCdc(this);RECTrc;GetClientRect(&rc);PatBlt(dc,rc.left,rc.top,rc.right,rc.bottom,WHITENESS);//刷上白色CSocket类网络通信编程步骤1.构造CSocket对象,如以下的形式:CSocketServersocket;2.利用CSocket对象的Create()函数创建WindowsSocket,Create()函数会调用Bind()函数将此Socket绑定到指定的地址上,其原型为:BOOLCreate(UINTnSocketPort=0,intnSocketType=SOCK_STREAM,LPCTSTRlpszSocketAddress=NULL);其中nSocketPort参数指定通信连接的端口号,端口号可以任意指定,但最好不要使用系统默认的一些端口号,例如21是FTP文件传输使用的端口号;3.Socket创建完毕之后,在服务器端进行监听客户的连接请求,使用如下的代码:ServerSocket.Listen();紧接着对于客户端而言,将会调用Connect()函数向服务器发送连接请求,而对于服务器而言,则会调用Accept()函数对客户端发送过来的请求连接进行接受和处理,Accept()函数可以创建一个和监听Socket相同的连接Socket来处理客户的请求,二原来的Socket仍然处于监听状态,使用的形式如下。客户端:ClientSocket.Connect(服务器的地址,服务器的端口号);服务器端:CSocketReceiveSocket;ServerSocket.Accept(连接Socket,客户的地址结构,客户地址结构的长度)4.对于数据流服务器类型而言,服务器和客户各自通过调用函数来完成数据的发送和接受,使用如下的语句:ServerReceive.Receive(缓冲区,缓冲区的长度,接受标志位);Client.Send(缓冲区,缓冲区的长度,发送标志位);5.在客户端与服务器端的数据传输完成之后,调用下述语句,释放Socket所占有的资源。ServerSocket.Close();ReceiveSocket.Close();ClientSocket.Close();
//获得菜单文本
pMenu->GetMenuString(i,m_MenuList[m_Index].m_MenuText,MF_BYPOSITION);
UINTMenuID=pMenu->GetMenuItemID(i);//获得菜单ID
//MenuID=-1,Toped=FALSE;表示弹出式菜单
if((MenuID=-1||MenuID==65535)&&Toped==TRUE)
MenuID=-2;
m_MenuList[m_Index].m_MenuType=MenuID;//设置菜单列表
//修改菜单风格
pMenu->ModifyMenu(i,MF_OWNERDRAW|MF_BYPOSITION|MF_STRING,m_MenuList[m_Index].m_MenuType,(LPSTR)&(m_MenuList[m_Index]));
m_Index+=1;
CMenu*pSubMenu=pMenu->GetSubMenu(i);//获得子菜单句柄
if(pSubMenu)
SetMenuItemInfo(pSubMenu,FALSE);//递归调用SetMenuItemInfo
returnTRUE;
F、然后在框架类或对话框类的OnCreate()函数或OnInitDialog()函数中调用SetMenuItemInfo函数,代码如下:
m_Menu.SetMenuItemInfo(&m_Menu);//设置菜单项
A、自定义状态栏指示器。
在资源的StringTable中添加:
IDS_STATE颜色
在MainFram.cpp中添加IDS_STATE
staticUINTindicators[]=
ID_SEPARATOR,//statuslineindicator
IDS_STATE,//添加的内容
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
B、在MainFrm.h中修改:
public:
CStatusBarm_wndStatusBar;//默认为私有,这里改为公有
C、在CmyTestView.cpp中加入#include“MainFrm.h”
D、在视类中的消息响应函数中添加:
CSizesz=dc.GetTextExtent(str);
CMainFrame*pFrame=(CMainFrame*)AfxGetMainWnd();
pFrame->m_wndStatusBar.SetPaneInfo(1,IDS_STATE,SBPS_NORMAL,sz.cx);
pFrame->m_wndStatusBar.SetPaneText(1,str);
如果顺序不对会有以下错误:
errorC2143:
syntaxerror:
missing';'before'*'
errorC2501:
'CMyTestView':
missingstorage-classortypespecifiers
'pv':
在任何cpp文件的开头都应该以这样的顺序:
#include"MyTestDoc.h"
#include"MyTestView.h"
#include"MainFrm.h"
注意,Doc的头文件一定要在最前面。
这样你的CDemoView和CMyView也可以共享一个CDemoDoc。
一般在Cpp中包含文件是要注意类的包含关系,被包含的类定义应该在前面。
如果实在有冲突,可以在一个类的头文件中加:
classCXXXDoc;之类的空定义。
这样定义过的头文件中可以用CXXXDoc申明指针,但是不能申明实际对象。
CDC及其派生类的继承视图:
Cobject
public|------CDC
public|------|------CClientDC
public|------|------CpaintDC
public|------|------CwindowDC
public|------|------CMetaFileDC
CClientDC:
(客户区设备上下文)用于客户区的输出,与特定窗口关联,可以让开发者访问目标窗口中客户区,其构造函数中包含了GetDC,析构函数中包含了ReleaseDC:
用法是:
CClientDCdc(this);//this一般指向本窗口或当前活动视图
dc.TextOut(10,10,str,str.GetLength());//利用dc输出文本,如果是在CScrollView中使用,还要注意调用OnPrepareDC(&dc)调整设备上下文的坐标。
CPaintDC用于响应窗口重绘消息(WM_PAINT)是的绘图输出。
CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中调用EndPaint()释放设备上下文。
EndPaint()除了释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。
因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。
CPaintDC也只能用在WM_PAINT消息处理之中。
CPaintDC:
CPaintDC(CWnd*pWnd)
...
if(!
Attach(:
BeginPaint(m_hWnd=pWnd->m_hWnd,&m_ps)))
AfxThrowResourceException();
~CPaintDC()
EndPaint(m_hWnd,&m_ps);
Detach();
CWindowDC:
关联一特定窗口,允许开发者在目标窗口的任何一部分进行绘图,包含边界与标题,这种DC同WM_NCPAINT消息一起发送
CWindowDC与CClientDC,CPaintDC的区别:
CWindowDC可在非客户区绘制图形,而CClientDC,CPaintDC只能在客户区绘制图形。
CWindowDC下坐标原点是在屏幕的左上角,CClientDC,CPaintDC下坐标原点是在客户区的左上角。
//CWindowDCdc(this);//this代表只能在view区域绘画
//CWindowDCdc(GetParent());//在整个frame区域绘画
CWindowDCdc(GetDesktopWindow());//可在整个桌面区域绘画
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
CClientDC与CPaintDC的区别:
CPaintDC的对象一般用在OnPaint内以响应Windows消息WM_PAINT,自动完成绘制,在整个窗口内进行重画,维持原有窗口完整性。
CClientDC应用在非响应Windows消息WM_PAINT的情况下,进行实时绘制,绘制的区域内被重画。
另外CDC和HDC都要手动释放。
HDChDC;
hDC=:
GetDC(m_hWnd);
MoveToEx(hDC,m_ptOrigin.x,m_ptOrigin.y,NULL);
LineTo(hDC,point.x,point.y);
ReleaseDC(m_hWnd,hDC);
CDC*pDC=GetDC();
pDC->MoveTo(m_ptOrigin);
pDC->LineTo(point);
ReleaseDC(pDC);
方法一:
此方法在设备结束时不会销毁原来的资源(即:
hDC,hBitmap)
CDC*pDC=CDC:
FromHandle(hDC);
方法二:
此方法在设备结束时会销毁原来的资源(即:
CDCdc;
dc.Attach(hDC);
CClientDCdc(this);
RECTrc;
GetClientRect(&rc);
PatBlt(dc,rc.left,rc.top,rc.right,rc.bottom,WHITENESS);//刷上白色
1.构造CSocket对象,如以下的形式:
CSocketServersocket;
2.利用CSocket对象的Create()函数创建WindowsSocket,Create()函数会调用Bind()函数将此Socket绑定到指定的地址上,其原型为:
BOOLCreate(UINTnSocketPort=0,intnSocketType=SOCK_STREAM,LPCTSTRlpszSocketAddress=NULL);
其中nSocketPort参数指定通信连接的端口号,端口号可以任意指定,但最好不要使用系统默认的一些端口号,例如21是FTP文件传输使用的端口号;
3.Socket创建完毕之后,在服务器端进行监听客户的连接请求,使用如下的代码:
ServerSocket.Listen();
紧接着对于客户端而言,将会调用Connect()函数向服务器发送连接请求,而对于服务器而言,则会调用Accept()函数对客户端发送过来的请求连接进行接受和处理,Accept()函数可以创建一个和监听Socket相同的连接Socket来处理客户的请求,二原来的Socket仍然处于监听状态,使用的形式如下。
客户端:
ClientSocket.Connect(服务器的地址,服务器的端口号);
服务器端:
CSocketReceiveSocket;
ServerSocket.Accept(连接Socket,客户的地址结构,客户地址结构的长度)
4.对于数据流服务器类型而言,服务器和客户各自通过调用函数来完成数据的发送和接受,使用如下的语句:
ServerReceive.Receive(缓冲区,缓冲区的长度,接受标志位);
Client.Send(缓冲区,缓冲区的长度,发送标志位);
5.在客户端与服务器端的数据传输完成之后,调用下述语句,释放Socket所占有的资源。
ServerSocket.Close();
ReceiveSocket.Close();
ClientSocket.Close();
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1