您的位置:首页 > 编程语言 > C语言/C++

阅读笔记《孙鑫-VC++深入详解》

2015-04-29 14:14 274 查看
《VC++深入详解》
       ——————2012/8
 
颜色对话框 CColorDialog
保存另存为对话框 CFileDialog  
字体对话框 CFontDialog    
 
1  (用API创建一个窗口)
 
2  (C++类的基本知识)
 
3  (MFC单文档执行流程)
 
4  (消息映射机制;
     MoveTo 、Lineto
     获取客户区DC,绘画CPen    CBrush)
     使窗口无效 Invalidate();
  刷新视图时默认的调用过程:CDocument::UpdateAllViews()   ->   CView::OnUpdate()   ->   CWnd::Invalidate()   ->   OnPaint()   ->  
OnDraw()
 
5  (txt文本制作,插入符、路径程? 
     GetTextExtent、GetTextMetrics区别
     卡拉OK字幕变色(DrawText、TextOut),
     定时器)
 
得到客户窗口矩形坐标 GetClientRect(&rect);
 

Class 6 .menu 

 若四个类(App、MainFrame、Doc、View)都有一个菜单按钮的响应函数,那么响应优先级是前面列出的反序,且只有一个函数会响应。
  菜单命令的路由过程:首先MainFrame类接受到消息,它将把消息传递给view类,若view类无处理函数,则转交给doc类,若也无处理函数则交还  给view类,view类再交还给mainframe类处理,若MainFrame也没有处理函数,则交给app来处理了。
创建一个弹出式菜单CreatePopupMenu;  添加到菜单栏最后AppendMenu;  删除指定的菜单DeleteMenu;  插入到菜单栏指定位置InsertMenu
 
Class 7 .dialog
GetDlgItem (控件ID )获取该对话框指定ID的控件指针
GetWindowText     获取控件的文本
SetWindowText     设置控件的文本
 
GetDlgItemText  /  SetDlgItemText      atoi     itoa
GetDlgItemInt  /  SetDlgItemInt
GetDlgItem->SendMessage ( ,WM_GETTEXT / WM_SETTEXT , , )
SendDlgItemMessageEM_SETSEL  :   SetFoucs
 
Edit控件
在聊天的时候,除了要滚动到最后一行显示外,还要把光标定位到最后。
m_edit.SetFocus(); 
int   n   =   m_edit.GetWindowTextLength(); 
m_edit.SetSel(n,   n,   FALSE);
 
在编辑框中输入文本立即做出反映,可利用消息响应EN_CHANGE
 
对话框上创建一个控件按钮,风格一般是WS_VISIBLE | WS_CHILDE
 
Class 8.propertysheet & propertyPage

CPropertySheet sheet(_T("Simple PropertySheet"));

 

CStylePage pageStyle;

CColorPage pageColor;

CShapePage pageShape;

 

sheet.AddPage(&pageStyle);

sheet.AddPage(&pageColor);

sheet.AddPage(&pageShape);

 

sheet.SetWizardMode();//若在此处添加该函数则属性页变为属性向导

 

sheet.DoModal();

 
设置属性向导的上一页下一页和完成按钮:
在CPropertyPage::OnSetActive函数中调用  CPropertySheet::SetWizardButtons 
在CPropertyPage::OnWizardNext函数中处理点击下一步按钮时的消息。先刷新updatedata
 
Group Box  +  Radio Button 
(第一个Radio的属性要选中group,并为它定义一个int变量,当updatedata刷新后,变量的值即为以0为开始的该组Radio的索引)  OnWizardNext()
在组框中绘图:CRect  rect ;   GetDlgItem(组框ID)->GetWindowRect(&rect);  ScreenToClient(&rect) ;  
这样就可以利用该矩形的坐标绘图了。
List Box   

 在对话框即将显示之前调用虚函数OnInitDialog()为该控件添加显示内容:((CListBox*)GetDlgItem(ID_LISTBOX))->AddString()。

为该控件定义一个CString变量,updatedata之后该变量值被用户选中的值刷新。

 
Grouo Box  +  check box

为每一个check关联一个bool变量。

 
Combo Box

Setcursel设置初始化edit默认的显示为索引为0的string

列表会自动排序,在控件属性上去掉sort选项,那么就会和自己添加的顺序一样。

为该控件定义一个变量 int型的索引  和 string型均可以。
对用户的选择结果可以不用updatedata实现映射,用getcursel和getlbtext组合也可。
 
向导框结束后,用户点击完成,domodal返回WIZFINISH。向导页的关联变量定义为public方便完成后在view类中访问。CPropertySheet为局部变量,此时窗口销毁了,但是对象还在,依然可以访问其中的成员。 调用InValidate函数使窗口无效,然后在OnDraw函数中实现在窗口中输出。
 
 
Class 9 修改窗口外观

修改图标,标题栏在框架窗口中修改。  修改客户区背景在view类中修改。(因为view覆盖在MainFrame上面的)

函数CMainFrame(CView)::PreCreateWindow(CREATESTRUCT& cs)中修改窗口的外观(窗口创建前)

在OnCreate函数末尾修改窗口外观(窗口创建后)

 

1. (修改光标,背景等)自定义并注册一个窗口类,注册并赋给cs.lpszClass

(修改标题栏,图标)直接修改cs的各成员变量。

因为:窗口的背景,消息处理函数,光标等是在定义窗口类时确定的,而窗口风格,最大最小化按钮,窗口大小是在注册窗口类之后创建窗口时设置的,所以可以通过cs直接改。

(创建后)调用全局函数SetWindowLong

 

2. (比上面的方法更方便)  cs.lpszClass = AfxRegisterWndClass  (创建前)
(常用)全局函数SetClassLong      (创建后(OnCreate函数))Cview中没有OnCreate函数,需自己添加WM_CREATEX的消息处理。
 
IsWindowVisible     ShowWindow( SW_SHOW / SW_HIDE )
ShowControlBar            SetCheck (复选标记,选上之后会在菜单栏前面加个勾)
 
设置状态栏创建进度栏。。。。。。。   
 
 
Class 10
CClientDC   dc(this);
画点:    dc.SetPoxel 
画线:    dc.MoveTo     LineTo
画矩形:  dc.Rectangle(CRect( ,))  
画椭圆:  dc.Ellipse
 
dc.SelectObject
画笔CPen、
画刷CBrush[要使新画的图形不覆盖原来的线条,应该将画刷设置为透明的,CBrush *p = CBrush::FromHandle ((HBRUSH)GetStockObject(NULL_BRUSH))得到一个透明的画刷,选入dc即可]
 

颜色对话框,字体对话框

 
设置对话框背景色WM_CTLCOLOR 消息响应函数OnCtlColor(CDC *pDC,CWnd *pWnd,UINT nCtlColor),返回一个用于绘制的指定画刷句柄。        会多次调用,对话框创建时调用,然后子窗口控件绘画时也要调用,pDC,pWnd均指向要绘制的控件,如果只绘制指定控件的颜色,可以在该函数中判断if(pWnd->GetDlgCtrID()==指定控件ID) { return 你要用的画刷}
SetWindowText设置文字的颜色   SetBkMode(TRANSPARENT)设置文字背景透明 
SetBkColor设置背景色
 
若要改变CButton的字体颜色和背景色需要 派生CButton类并重写DrawItem函数,然后把该派生类对象与对话框中的按钮控件相关联。且在按钮控件的属性中要选中OwnerDraw
 
GetClientRect
位图:BitBlt按位拷贝   StretchBlt压缩放大拷贝.GetBitmap获取位图的宽高。
使窗口无效,窗口重绘经过两步:1,擦除背景OnEraseBkgnd;2,绘图OnDraw        
如果重绘时窗口闪动大,则把绘图的操作写到OnEraseBkgnd中会好一点,因为在这个函数中绘图则不调用基类的OnEraseBkgnd,即不擦除背景就直接绘制了。
 
 
Class 11 图形的绘制和保持
MFC 集合类 CPreArray
Win32相应WM_PAINT消息绘图时,获取DC只能使用BeginPaint,EndPaint,且只能在painting消息中使用。它们封装在CPaintDc中。    而CClientDC封装了GetDC和ReleaseDC。
 
CScrollView 带滚动条的窗口
视口与窗口,  页面坐标(逻辑)   设备坐标(物理)
虚函数OnInitialUpdate  窗口刚完全创建时第一个调用的函数,可用来完成一些完后创建窗口后的初始化工作。
OnPrepareDC调整例如带滚动条之类的窗口。(逻辑坐标到设备坐标的映射)
Class 12  文件读写
memset    memcpy    memmove
 
C文件操作:
FILE * pFile = fopen(filename, openmode);
fwrite 、 fread 、 fclose 、  fseek(移动文件指针到指定位置)、 ftell(从当前指针位置得到文件长度)    rewind(重新放置文件指针到开始处)
对文本的写入和读取应该保持一样,文本方式、二进制方式。因为文本方式的读写会做一些转换。如果以文本方式写二进制方式读则可能出现错误。
C++文件操作:
类: ofstream  ifstream  fstream
常用成员函数:write  read  close
Win32 API文件操作:
创建或打开(不仅文件):CreateFile ,关闭(CloseHandle) ,可设置共享,安全性,异步同步读写等等
写入:WrireFile         读取:ReadFile
MFC文件操作:
类:   CFile     (使用很方便)无缓冲
 
打开、保存对话框     CFileDialog类
CFileDialog类中一个重要的结构类型:m_ofn
win.ini文件信息存储与删除
::WriteProfileString函数用于兼容16系统写win.ini文件(一般用在CApp类的InitInstance虚函数中对注册表操作函数(SetRegistryKey)之下。)
::GetProfileString     获取键相关的字符串
 
CWinApp也继承了这两个函数,但是有区别,win2000以上的系统是写在注册表之中。
在32位系统中应该直接对注册表进行操作。
可查看注册表目录:HKEY_CURRENT_USER\Software\应用程序向导生成的本地应用程序
 
注册表操作
RegCreateKey(HEY_LOCAL_MACHINE,”Software\\ www.sunxin.org\\admin”,&hKey)
RegSetValue(hKey,NULL,REG_SZ,”zhangsan”,strlen(“zhangsan”)) //使用该函数只能设置REG_SZ类型的值    
若要设置其他值则应该用RegSetValueEx
RegCloseKey(hKey)
 
RegQueryValue(HKEY_LOCAL_MACHINE,” Software\\ www.sunxin.org\\admin”,pBuf,&value)
用RegSetValueEx设置的其他类型值查询用 RegOpenKey  +  RegQueryValueEx
 
文档串行化
类:   CArchive   必须在创建之前先创建一个CFile对象与之关联,而且访问文件的模式要相同                         输入输出串行化,重载了  >>    <<
 
 
MFC文档类串行化
一个文档对象与一个文件关联,通过CArchive操作。        集合类CObArray
有关文件读写操作在CDoc::Serialise(CArchive &ar);函数中,点击窗口的打开和保存按钮触发函数的消息相应。由语句if(ar.IsStoring())判断是保存还是打开。
编写自己的可串行化的类时,要保存自己定义的这个类的对象要为该类定义自己的serialise函数,doc类的函数在执行保存打开时会自动调用你定义的serialise函数。支持串行化的mfc类都定义了serialise函数
 
CWinApp管理文档链表,而每个文档关联一个框架和视图类(一个文档可以和多个视类关联,一个视类只能和一个文档关联),文档负责保存和加载数据(serialize),视图负责显示数据(ondraw)。
 
在文档类获取视图类的指针:
POSITION  pos = GetFirstViewPosition();
CGraghView  *pView = (CGrangh*)GetNextView(pos);
 
示图类获取文档类的指针:视图类自己定义了一个函数能获取文档类的指针。
 
关闭文档、onopendocument 和 onnewdocument 都会调用 deletecontents,特别是单文档分配了堆内存记得使用该函数释放。
 
Class14 网络编程
16位端口,1024及以下保留。
TCP/IP采用16位或32位整数高位先存。
 
TCP
服务器端:

1、 创建套接字(socket)。

2、 将套接字绑定到一个本地地址和端口上(bind)。

3、 将套接字设为监听模式,准备接受客户请求(listen)。

4、 等待客户请求到来:当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。

5、 用返回的套接字和客户端进行通信(send/recv)。

6、 返回,等待另一个客户请求。

7、 关闭套接字。(closesocket)
客户端:

1、 创建套接字(socket)。

2、 向服务器发出连接请求(connect)。

3、 和服务器端进行通信(send/recv)。

4、 关闭套接字
 
UDP
服务器(接收端):

1、 创建套接字(socket)。

2、 将套接字绑定到一个本地地址和端口上(bind)。

3、 等待接受数据(recvfrom)。

4、 关闭套接字。
客户端(发送端):

1、 创建套接字(socket)。

2、 向服务器发送数据(sendto)。

3、 关闭套接字。
 
开始时应该调用WSAStartup启动库,结束后调用WSACleanup
 
Class 15,16 多线程、同步、聊天室
创建线程: CreateThread  //创建返回线程的句柄应立即用CloseHandle关闭。
线程函数形式DWORD WINAPI ThreadProc(LPVOID lpParameter)
互斥对象: HANDLE  hMutex= CreateMutex  //如果创建命名的对象先前已经存在,且调用GetLastError()返回ERROR_ALREADY_EXISTS,则返回之前创建的对象的句柄。(可用于一个程序只能有一个实例的实现。)  

WaitForSingleObject(hMutex,INFINITE)   (使用之前申请)无信号时等待  

ReleaseMutex(hMutex)        (不使用时释放)让互斥量有信号
互斥对象里有一个计数器和访问线程的ID。谁拥有互斥对象只能由谁释放(请求多少次就应该释放多少次)。     若请求得到之后,线程关闭,但未释放,则操作系统会自动释放。其他线程任然能申请到。
 
(lesson 16)事件对象(线程同步)
CreateEvent,  SetEvent,  ResetEvent    申请用WaitForSingleObject
注意:人工重置,有信号时,所有的等待线程都能运行,需要手动调用reset,但还是不能实现同步。所以最好使用自动重置,有信号时只能有一个线程变为可调度,同时os会设置该对象为非信号,不需手动调用reset。
(可用于一个程序只能有一个实例的实现。)
 
(lesson 16)关键代码段(线程同步)
InitializeCriticalSection    EnterCriticalSection,  LeaveCriticalSection     DeleteCriticalSection
 
互斥对象、事件对象、关键代码段:
前两者属于内核对象,进行线程同步较慢,可以实现多个进程间的线程同步。关键代码段是工作在用户方式下,同步速度快,但是容易出现死锁,因为等在时无法设定超时值。 
 
 
聊天室
MFC中加载套接字可用AfxSocketInit,1.1版本,结束时系统会自动调用WSACleanup。
//Call this function in your CWinApp::InitInstance override to initialize Windows Sockets
使用这个函数应该在预编译头文件(stdafx)中加入afxsock.h,这样也不需要手动连接库文件。
 
线程函数可以定义为类静态函数。或全局函数。
 
CEdit控件中要支持换行,则属性中应该选择multiline,然后在CString中有\r\n则换行。
CIPAddressCtrl   IP控件类。
DWORD  dwIP;
((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);//获取控件中的ip地址(主机字节序)。
 
消息传递:
#define   WM_   (WM_USER+1)
::PostMessage(hWnd,WM_,wParam,lParam)  
ON_MESSAGE(WM_ , proc)
 
非阻塞的套接字异步选择机制:
利用消息传递机制(性能更高)
WSAAsyncSelect设置抛出消息    WSAEnumProtocols     WSASocket (socket函数的扩展)   带WSA的均为windows的扩展。
WSARecvFrom,  WSASendTo,    sunxi PPT中有详解
 
用主机名获得ip地址:gethostbyname   <->   gethostbyaddr
HOSTENT  * pHost;
pHost = gethostbyname(edit_name);
addrto.sin_addr.S_un.S_addr = *((DWORD*)pHost->h_addr_list[0]);
 
Class 17.进程间通信
剪贴板
OpenClipboard   EmptyClipboard   SetClipboardData
CloseClipboard      
匿名管道
 
 
命名管道
 
 
邮槽
 
 
Class 18. ActiveX
属性、事件、方法。
 
增加activex控件到工程会自动添加一个该控件的类。Project -> Add To Project ->Comgeonents and Contrls
 
Class 19.动态链接库
_declspec(dllexport) 导出函数需要在前面增加该语句。声明时应该使用_declspec(dllimport)该语句而不使用extern,这样效率更高。
GetForegroundWindow()获取当前用户窗口
extern  “C”采用c语言编译方式到处库函数。(而不采用c++名字改编),不能导出类的成员函数,只能导出全局函数  
模块定义文件。。。。。。。。。即使是_stdcall也不会采用c++的名字改编
 
动态加载一个动态链接库:LoadLibrary     GetProcAddress  只加载需要的函数,节省内存空间,提高性能   FreeLibrary
 
DllMain
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: