孙鑫vc课程笔记
- 格式:doc
- 大小:109.00 KB
- 文档页数:24
1,弹出菜单(Pop-up)是不能用来作命令响应的。
1,弹出菜单(Pop-up)是不能用来作命令响应的。
2,MFC中菜单项消息如果利用ClassWizard来对菜单项消息分别在上述四个类中进行响应,则菜单消息传递顺序:View类--Doc类--CMainFrame类--App类。
菜单消息一旦在其中一个类中响应则不再在其它类中查找响应函数。
具体:当点击一个菜单项的时候,最先接受到菜单项消息的是CMainFrame框架类,CMainFra me框架类将会把菜单项消息交给它的子窗口View类,由View类首先进行处理;如果View 类检测到没对该菜单项消息做响应,则View类把菜单项消息交由文档类Doc类进行处理;如果Doc类检测到Doc类中也没对该菜单项消息做响应,则Doc类又把该菜单项消息交还给View类,由View类再交还给CMainFrame类处理。
如果CMainFrame类查看到CMainFrame 类中也没对该消息做响应,则最终交给App类进行处理。
3,消息的分类:标准消息,命令消息,通告消息。
[标准消息]:除WM_COMMAND之外,所有以WM_开头的消息。
[命令消息]:来自菜单、加速键或工具栏按钮的消息。
这类消息都以WM_COMMAND呈现。
在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的w Param参数识别。
[通告消息]:由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。
这类消息也是以WM_COMMAND形式呈现。
说明:1)从CWnd派生的类,都可以接收到[标准消息]。
2)从CCmdTarget派生的类,都可以接收到[命令消息]和[通告消息]。
4,一个菜单拦可以有若干个子菜单,一个子菜单又可以有若干个菜单项等。
对菜单栏的子菜单由左至右建立从0开始的索引。
对特定子菜单的菜单项由上至下建立了从0开始的索引。
第一课Windows程序内部运行原理1.MFC生成的C++源文件中都有StdAfx.h,此文件包含了常用的AFX函数的声明,其中有afxwin.h,此文件包含了CRECT,CPoint,CWnd等许多类及其方法的声明。
2.Project->Setting->Debug可以加入命令行参数。
3.在SDK中要加入"windows.h"和stdio.h。
因为LoadCursor,MessageBox等函数的声明在这个文件中。
4.创建一个完整的窗口的四个步骤SDK,1设计窗口类,2注册窗口类,3创建窗口,4显示窗口5.函数名可以代表函数代码的首地址,即可作为函数指针。
6.要查看VC数据类型,可以在MSDN中输入“BOOL”然后选择“DATA TYPE”。
7.atof将字符串转化为float,atoi将字符串转化为int型。
8.所有从CWnd类派生的类都有m_hWnd句柄。
9.变量的生命周期:可以认为出了包含它的大括号,这个变量的生命周期结束。
所以全局变量的声明位于所有大括号之外。
但是用new声明的变量和用static声明的变量除外。
10.SDK示范程序,见下面。
11.sprintf格式化字符,其头文件为stdio.h,在MFC中格式化字符用CString.Format12.GetDC()与ReleaseDC()要成对使用,否则会内存泄漏。
同样,BeginPaint()与EndPaint()。
13.GetStockObject()得到画笔、画刷、字体、调色板的句柄,使用时必须用类型转换。
14.什么时候用NULL,什么时候用0.答,对指针赋值时用NULL,对变量赋值时用0.15.15.什么是野指针?答:将指针指向的变量的内存释放后,此指针即变成野指针!如何避免野指针?答:将此指针指向NULL即可。
p=NULL;16.SDK代码流程:#include "windows.h"//包含头文件LoadCursor,TextOut等函数#include "stdio.h"//包含sprintf,printf等函数LRESULT CALLBACK MyProc(...);//声明回调函数int WINAPI WinMain(){WNDCLASS wndcls;//设计窗口类wndcls.hcursor=LoadCursor();//初始化....RegisterClass(&wndcls);//注册窗口类hwnd=CreateWindow(...);//创建窗口ShowWindow(..);//显示窗口UpdateWindow(..);MSG msg;//定义消息结构体while(GetMessage(...))//消息循环{...}return 0;}LRESULT CALLBACK MyProc(...)//实现回调函数{switch(uMsg){case WM_CHAR:break;...}}第二课掌握C++1.定义结构体和类时别忘记在最后加入";"号!例如Class Point{int x;int y;};2.#include <xxx.h>与#include "xxx.h"的区别:<>不查找运行时目录,""查找运行时目录!3.类的定义中,如果未指明成员类型,则缺省为private.而结构体中则缺省为public.4.引用:引用经常用在函数的传参上。
1,创建插入符:void CreateSolidCaret( int nWidth, int nHeight );//创建插入符void CreateCaret( CBitmap* pBitmap );//创建位图插入符void ShowCaret( );//显示插入符void HideCaret( );//隐藏插入符static void PASCAL SetCaretPos( POINT point );//移动插入符号说明:1)创建插入符要在窗口创建完成之后,CreateSolidCaret函数创建的插入符被初始化为隐藏,所以需要调用ShowCaret()将其显示。
2)使用CreateCaret函数创建位图插入符的时候,不能使用局部的位图对象关联位图资源。
(与资源相关联的C++对象,当它析构的时候会同时把与它相关联的资源销毁。
)2,获取当前字体信息的度量:CDC::GetTextMetricsBOOL GetTextMetrics( LPTEXTMETRIC lpMetrics ) const;说明:typedef struct tagTEXTMETRIC { /* tm */int tmHeight;//字体高度。
Specifies the height (ascent + descent) of characters.int tmAscent;//基线以上的字体高度int tmDescent;//基线以下的字体高度int tmInternalLeading;int tmExternalLeading;int tmAveCharWidth;//字符平均宽度int tmMaxCharWidth;int tmWeight;BYTE tmItalic;BYTE tmUnderlined;BYTE tmStruckOut;BYTE tmFirstChar;BYTE tmLastChar;BYTE tmDefaultChar;BYTE tmBreakChar;BYTE tmPitchAndFamily;BYTE tmCharSet;int tmOverhang;int tmDigitizedAspectX;int tmDigitizedAspectY;} TEXTMETRIC;3,OnDraw函数:virtual void OnDraw( CDC* pDC )当窗口(从无到有或尺寸大小改变等)要求重绘的时候,会发送WM_PAIN消息,调用OnDraw函数进行重绘。
孙鑫vc++视频讲座笔记(七)模态对话框和非模态对话框A modal dialog box must be closed by the user before the application continues.A modeless dialog box allows the user to display the dialog box and return to another task without canceling or removing the dialog box.创建模态对话框 CDialog::DoModal 返回一个int值,结束这个模态窗口时候,传递这个int值给CDialog::EndDialog(int)。
DoModal函数本身有显示的作用,不用show函数非模态对话框使用CDialog::Create 创建{……CDlgTest dlg;dlg.Create(IDD_DIALOG1,this);dlg.ShowWindow(SW_SHOW);]……}dlg是个局部变量,所以这样对话框不会显示,可以将dlg改为一个指针,然后在堆上分配内存如CDlgTest *pdlg = new CDlgTest();(会造成内存泄露)或者将dlg作为一个类的成员变量,或者将dlg声明为static。
在非模态对话框上点击“确定”按钮是将窗口隐藏,而模态对话框则是销毁。
这个是由基类的虚函数OnOk函数响应。
CDialog::OnOKvirtual void OnOK( );If you implement the OK button in a modeless dialog box, you must override the OnOK member functio n and call DestroyWindow from within it. Don’t call the base-class member function, because it calls EndDialog, which makes the dialog box invisible but does not destroy it.所以必须调用DestroyWindow函数。
作者tag:windows/.net孙鑫vc++讲座笔记 CSDN 推荐孙鑫VC++讲座笔记-(1)Windows程序内部运行机制1,windows程序设计是种事件驱动方式的程序设计,主要基于消息的。
当用户需要完成某种功能时,需要调用OS某种支持,然后OS将用户的需要包装成消息,并投入到消息队列中,最后应用程序从消息队列中取走消息并进行响应。
2,消息结构:typedef struct tagMSG { // msgHWND hwnd; //接收消息的窗口句柄。
和哪个窗口相关联。
UINT message; //消息标识。
消息本身是什么。
WPARAM wParam; //消息的附加信息。
具体取决于消息本身。
LPARAM lParam;DWORD time; //消息投递时间。
POINT pt; //消息投递时,光标在屏幕上的位置。
} MSG;3,消息队列:每个应用程序OS都为它建立一个消息队列,消息队列是个先进先出的缓冲区,其中每个元素都是一个消息,OS将生成的每个消息按先后顺序放进消息队列中,应用程序总是取走当前消息队列中的第一条消息,应用程序取走消息后便知道用户的操作和程序的状态,然后对其处理即消息响应,消息响应通过编码实现。
4,使用VC编程除了良好的C基础外还需要掌握两方面:一,消息本身。
不同消息所代表的用户操作和应用程序的状态。
二,对于某个特定的消息来说,要让OS执行某个特定的功能去响应消息。
5,Window程序入口:int WINAPI WinMain(HINSTANCE hInstance, // 当前事例句柄。
HINSTANCE hPrevInstance, // 先前事例句柄。
LPSTR lpCmdLine, // 命令行指针int nCmdShow // (窗口)显示的状态);说明:WinMain函数是Windows程序入口点函数,由OS调用,当OS启动应用程序的时候,winmain函数的参数由OS传递的。
6,创建一个完整的窗口需要经过下面四个操作步骤:一,设计一个窗口类;如:WNDCLASS wndcls;二,注册窗口类;如:RegisterClass(&wndcls);三,创建窗口;如:CreateWindow(),CreateWindowEX();四,显示及更新窗口。
如:ShowWindow(),UpdateWindow();说明:创建窗口的时候一定要基于已经注册的窗口类.7,Windows提供的窗口类:typedef struct _WNDCLASS {UINT style; //窗口的类型WNDPROC lpfnWndProc; //窗口过程函数指针(回调函数)int cbClsExtra; //窗口类附加字节,为该类窗口所共享。
通常0。
int cbWndExtra; //窗口附加字节。
通常设为0。
HANDLE hInstance; //当前应用程序事例句柄。
HICON hIcon; //图标句柄LoadIcon();HCURSOR hCursor; //光标句柄LoadCursor();HBRUSH hbrBackground; //画刷句柄(HBRUSH)GetStockObject();LPCTSTR lpszMenuName; //菜单名字LPCTSTR lpszClassName; //类的名字} WNDCLASS;8,窗口类注册:ATOM RegisterClass(CONST WNDCLASS *lpWndClass // address of structure with class// data);9,创建窗口:HWND CreateWindow(LPCTSTR lpClassName, // pointer to registered class name LPCTSTR lpWindowName, // pointer to window nameDWORD dwStyle, // window styleint x, // horizontal position of windowint y, // vertical position of windowint nWidth, // window widthint nHeight, // window heightHWND hWndParent, // handle to parent or owner window HMENU hMenu, // handle to menu or child-window identifier HANDLE hInstance, // handle to application instanceLPVOID lpParam // pointer to window-creation data);10,显示和更新窗口窗口:BOOL ShowWindow(HWND hWnd, // handle to windowint nCmdShow // show state of window);BOOL UpdateWindow(HWND hWnd // handle of window);11,消息循环:MSG msg;while(GetMessage(&msg,...)) //从消息队列中取出一条消息{TranslateMessage(&msg); //进行消息(如键盘消息)转换DispatchMessage(&msg); //分派消息到窗口的回调函数处理,(OS调用窗口回调函数进行处理)。
}其中://**The GetMessage function retrieves a message from the calling thread's message queue and places it in the specified structure.//**If the function retrieves a message other than WM_QUIT, the return value is nonzero.If the function retrieves the WM_QUIT message, the return value is zero. If there is an error, the return value is -1.BOOL GetMessage(LPMSG lpMsg, // address of structure with messageHWND hWnd, // handle of windowUINT wMsgFilterMin, // first messageUINT wMsgFilterMax // last message);//The TranslateMessage function translates virtual-key messages into character messages. The character messages are posted to the calling thread's message queue, to be read the next time the thread calls the GetMessage or PeekMessage function.BOOL TranslateMessage(CONST MSG *lpMsg // address of structure with message);//The DispatchMessage function dispatches a message to a window procedure. LONG DispatchMessage(CONST MSG *lpmsg // pointer to structure with message);12,窗口过程函数(回调函数)原型:The WindowProc function is an application-defined function that processes messages sent to a window. The WNDPROC type defines a pointer to this callback function. WindowProc is a placeholder(占位符)for the application-defined function name.LRESULT CALLBACK WindowProc( //这里WindowProc是个代号名字。
HWND hwnd, // handle to windowUINT uMsg, // message identifierWPARAM wParam, // first message parameterLPARAM lParam // second message parameter);说明:两种函数调用约定(__stdcall 和__cdecl):#define CALLBACK __stdcall//__stdcall 标准调用预定,是PASCAL 调用约定,象DELPHI使用的就是标准调用约定#define WINAPIV __cdecl// __cdecl 是C 语言形式的调用约定。
主要区别:函数参数传递顺序和对堆栈的清除上。
问题:除了那些可变参数的函数调用外,其余的一般都是__stdcall约定。
但C/C++编译默然的是__cdecl约定。
所以如果在VC等环境中调用__stdcall约定的函数,必须要在函数声明的时加上__stdcall 修饰符,以便对这个函数的调用是使用__stdcall约定(如使用DELPHI编写的DLL时候)。
(VC中可通过这途径修改:project|settings..|c/c++|...)在窗口过程函数中通过一组switch语句来对消息进行处理:如:LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam){switch(uMsg){case WM_PAINT:...break;case ...break;case WM_CLOSE://DestroyWindow(hwnd);//销毁窗口,并发送WM_DESTROY消息。
break;case WM_DESTROY://PostQuitMessage(0);//发送WM_QUIT消息到消息队列中,请求终止。