1、WindowsWindows程序设计程序设计信息工程学院信息工程学院图形用户界面(GUI)nWindows是一个具有可视化图形用户界面是一个具有可视化图形用户界面的多任务操作系统。的多任务操作系统。n它为用户提供了风格统一的由窗口它为用户提供了风格统一的由窗口(window)、菜单、菜单(menu)、工具栏、工具栏(toolbar)、控件控件(control)等界面元素所构成的多任务环等界面元素所构成的多任务环境。境。Windows编程模式nWindows 操作系统完全不同于单任务的操作系统完全不同于单任务的DOS操作系统,具有图形用户界面、多任操作系统,具有图形用户界面、多任务、多窗口等特点
2、。务、多窗口等特点。nWindows下的图形用户界面程序开发:下的图形用户界面程序开发: 直接使用直接使用Windows API函数函数 微软基础类库微软基础类库MFC(面向对象程序设计)(面向对象程序设计) wxWidget等(面向对象程序设计)等(面向对象程序设计) 基于Windows API的程序设计nWindows API (Application Programming Interface)是是Windows系统和系统和Windows 应用应用程序间的标准接口,为应用程序提供程序间的标准接口,为应用程序提供Windows支持的函数定义、参数定义和消支持的函数定义、参数定义和消息格式等
3、。息格式等。nWindows API:包含:包含Windows应用程序的函应用程序的函数调用、数据类型和结构。数调用、数据类型和结构。基于Windows API的程序设计n第一个第一个Windows程序:程序:“Hello world!”n窗口和消息窗口和消息n图形基础图形基础n控件类(子窗口类)控件类(子窗口类)n应用实例:简易计算器的实现应用实例:简易计算器的实现1. Hello world!nCode:Blocks下新建一个空的下新建一个空的.cpp(或(或.c)文件,文件中录入下列代码:文件,文件中录入下列代码:1. Hello world!n程序编译运行结果程序编译运行结果1. He
4、llo world!n解释解释1:头文件:头文件类型定义类型定义内核函数、用户接口函数和图形设备接口函数内核函数、用户接口函数和图形设备接口函数1. Hello world!n解释解释2:程序入口点:程序入口点WinMain(4个参数)个参数)1. Hello world!n解释解释2:程序入口点:程序入口点WinMain(4个参数)个参数) hInst是唯一标识本程序的实例句柄,系统和其是唯一标识本程序的实例句柄,系统和其它应用程序通过该句柄与本程序通讯。它应用程序通过该句柄与本程序通讯。 hPrevInst是本程序的前一个实例句柄,是本程序的前一个实例句柄,32位位Windows版本中该参
5、数始终为版本中该参数始终为NULL。 lpCmdLine是一个字符串指针,用于运行程序是一个字符串指针,用于运行程序的命令行。的命令行。nShowCmd指出程序最初显示的方式。指出程序最初显示的方式。1. Hello world!n解释解释2:程序入口点:程序入口点WinMain返回值返回值#define WINAPI _stdcall指定了一种调用方式:如何生成机器代码以在指定了一种调用方式:如何生成机器代码以在堆栈中放置函数调用的参数堆栈中放置函数调用的参数1. Hello world!n解释解释3:MessageBox函数函数1. Hello world!n解释解释3:MessageBo
6、x函数(函数(4个参数)个参数)第一个参数:窗口句柄第一个参数:窗口句柄第二个参数:消息框中显示的字符串第二个参数:消息框中显示的字符串第三个参数:标题栏字符串第三个参数:标题栏字符串最后一个参数:消息框按钮类型最后一个参数:消息框按钮类型n#define MB_OK0 x0000n#define MB_OKCANCEL0 x0001n#define MB_ABORTRETRYIGNORE 0 x0002n#define MB_YESNOCANCEL0 x00032. 窗口和消息窗口和消息n什么是窗口什么是窗口?屏幕上的一个可以接收用户输入,并以文本或图屏幕上的一个可以接收用户输入,并以文本或
7、图形的格式显示输出内容的区域。形的格式显示输出内容的区域。n什么是消息?什么是消息?消息描述了事件的类别,包括在图形用户消息描述了事件的类别,包括在图形用户界面内下的输入选择、鼠标按键、键盘按界面内下的输入选择、鼠标按键、键盘按键、窗口被创建、关闭和改变等。键、窗口被创建、关闭和改变等。2.1 一个典型的窗口程序一个典型的窗口程序nCode:Blocks下下Windows程序的创建程序的创建2.1 一个典型的窗口程序一个典型的窗口程序nCode:Blocks下下Windows程序的创建程序的创建2.1 一个典型的窗口程序一个典型的窗口程序nCode:Blocks下下Windows程序的创建程序
8、的创建2.1 一个典型的窗口程序一个典型的窗口程序n代码生成及运行结果代码生成及运行结果2.1 总体考虑总体考虑n很难记住很难记住Windows程序的所有语法,故向导程序的所有语法,故向导自动生成一个框架。自动生成一个框架。n两个主要函数两个主要函数WinMain和和WndProc。nWindows函数:如函数:如LoadIcon、ShowWindow等。等。n新的数据类型和宏定义:如新的数据类型和宏定义:如HWND、MSG、WNDCLASSEX等。等。2.1 总体考虑总体考虑LRESULT CALLBACK WindowProcedure ();int WINAPI WinMain (HIN
9、STANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) HWND hwnd; MSG messages; WNDCLASSEX wincl; wincl.hInstance = hThisInstance; . if (!RegisterClassEx (&wincl) return 0; hwnd = CreateWindowEx(.); ShowWindow (hwnd, nCmdShow); while (GetMessage (&messages, NULL, 0, 0) Tran
10、slateMessage(&messages); DispatchMessage(&messages); return messages.wParam;2.1 总体考虑总体考虑LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) /* handle the messages */ case WM_DESTROY: PostQuitMessage (0); break; default: /* for messages that we do
11、nt deal with */ return DefWindowProc (hwnd, message, wParam, lParam); return 0;2.2 事件驱动与消息循环事件驱动与消息循环启动启动输入姓名输入姓名输入第一次测试成绩输入第一次测试成绩输入第二次测试成绩输入第二次测试成绩输入第三次测试成绩输入第三次测试成绩计算平均成绩计算平均成绩结束结束启动启动消息处理消息处理结束结束输入姓名输入姓名输入第一次成绩输入第一次成绩输入第二次成绩输入第二次成绩输入第三次成绩输入第三次成绩计算平均成绩计算平均成绩过程驱动过程驱动事件驱动事件驱动2.2 事件驱动与消息循环事件驱动与消息循环启
12、动启动消息处理消息处理结束结束输入姓名输入姓名输入第一次成绩输入第一次成绩输入第二次成绩输入第二次成绩输入第三次成绩输入第三次成绩计算平均成绩计算平均成绩2.2 事件驱动与消息循环事件驱动与消息循环2.2 事件驱动与消息循环事件驱动与消息循环2.2 事件驱动与消息循环事件驱动与消息循环 while (GetMessage (&messages, NULL, 0, 0) TranslateMessage(&messages); DispatchMessage(&messages); 2.2 事件驱动与消息循环事件驱动与消息循环LRESULT CALLBACK WindowProcedure (H
13、WND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) case WM_DESTROY: PostQuitMessage (0); break; case WM_PAINT: break;2.2 事件驱动与消息循环事件驱动与消息循环LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) default: return DefWindowProc (hwnd
14、, message,wParam, lParam); return 0;2.3 Windows函数函数和新数据类型和新数据类型n函数函数LoadIcon、LoadCursorRegisterClassEx:注册窗口:注册窗口CreateWindowEx:创建窗口:创建窗口ShowWindow:显示窗口:显示窗口GetMessage、TranslateMessage等等2.3 Windows函数函数和新数据类型和新数据类型n新数据类型新数据类型typedef void* PVOID;typedef PVOID HANDLE;typedef HANDLE HDC;typedef HANDLE HI
15、NSTANCE;typedef HANDLE HWND;typedef long LONG_PTR;typedef unsigned int UINT_PTR;typedef UINT_PTR WPARAM;typedef LONG_PTR LPARAM;typedef CHAR *PSTR;2.3 Windows函数函数和新数据类型和新数据类型n新数据类型新数据类型typedef struct tagWNDCLASSEX UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANC
16、E hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; HICON hIconSm; WNDCLASSEX, *PWNDCLASSEX;2.3 Windows函数函数和新数据类型和新数据类型n新数据类型新数据类型typedef struct tagMSG HWND hWnd;/指定消息发向的窗口句柄指定消息发向的窗口句柄UINTmessage;/标识消息的消息值标识消息的消息值WPARAMwParam;/消息参数消息参数LPARAM
17、lParam;/消息参数消息参数DWORDtime;/消息进入队列的时间消息进入队列的时间POINT pt; /消息进入队列时鼠标指针的屏幕坐标消息进入队列时鼠标指针的屏幕坐标 MSG,*PMSG,NEAR *NPMSG, FAR * LPMSG;2.3 Windows函数函数和新数据类型和新数据类型n新数据类型新数据类型message是标识消息的消息值或消息名是标识消息的消息值或消息名#define WM_CREATE 0X0001 /创建窗口产生的消息创建窗口产生的消息#define WM_DESTROY 0X0002 /撤销窗口产生的消息撤销窗口产生的消息#define WM_PAINT
18、 0X000F /重画窗口产生的消息重画窗口产生的消息#define WM_CLOSE 0X0010 /关闭窗口产生的消息关闭窗口产生的消息#define WM_CHAR 0X0102 /按下非系统键产生的字符消息按下非系统键产生的字符消息#define WM_USER 0X0400 /用户自定义消息用户自定义消息#define WM_LBUTTONDOWN 2.3 Windows函数函数和新数据类型和新数据类型n新数据类型新数据类型wParam和和lParam都是都是32位消息参数,对位消息参数,对message进行补充。进行补充。例如:例如:WM_LBUTTONDOWN:产生单击鼠标左键的
19、消息产生单击鼠标左键的消息lParam高字节包含当前光标的高字节包含当前光标的Y坐标值坐标值低字节包含当前光标的低字节包含当前光标的X坐标值坐标值wParam包含一整数值以标识鼠标键的包含一整数值以标识鼠标键的按下状态按下状态MK_LBUTTON按下鼠标按下鼠标MK_MBUTTON 按下鼠标按下鼠标MK_RBUTTON按下鼠标按下鼠标3. 图形基础图形基础(GDI)n图形设备接口图形设备接口(GDI)是是Windows的子系统,的子系统,负责在屏幕或打印机上输出图形。负责在屏幕或打印机上输出图形。nGDI函数调用函数调用获取和释放设备描述表函数,如获取和释放设备描述表函数,如GetDC等。等。
20、绘图函数,如绘图函数,如TextOut等。等。设置和获取设备描述表参数的函数,如设置和获取设备描述表参数的函数,如SetTextColor等。等。其它其它3. 图形基础图形基础(GDI)n设备描述表函数设备描述表函数(DC)包含包含GDI函数如何在设备上工作的属性信息。函数如何在设备上工作的属性信息。如:显示文本信息时,字体、文本颜色以及字如:显示文本信息时,字体、文本颜色以及字符间距等属于设备描述表中的信息。符间距等属于设备描述表中的信息。3.1 字体显示字体显示n字体显示:在窗口过程中添加代码字体显示:在窗口过程中添加代码case WM_PAINT: HDC hdc; PAINTSTRUC
21、T ps; hdc = BeginPaint(hwnd, &ps); SetTextColor(hdc, RGB(255,0,0); TextOut(hdc, 100, 100, Hello world!, 12); EndPaint(hwnd, &ps);break;3.2 图形绘制图形绘制n图形绘制:椭圆图形绘制:椭圆 case WM_PAINT: HDC hdc; PAINTSTRUCT ps; HBRUSH hBrush; hdc = BeginPaint(hwnd, &ps); hBrush = CreateSolidBrush(RGB(0,128,255); SelectObjec
22、t(hdc, hBrush); Ellipse (hdc, 250, 100, 450,250); EndPaint(hwnd, &ps); break;4. 控件类控件类n控件:一种特殊的窗口(子窗口)控件:一种特殊的窗口(子窗口)按钮按钮静态静态滚动条滚动条编辑编辑列表框等列表框等4.1 按钮类按钮类n子窗口的创建子窗口的创建HWND CreateWindow(类名,类名,/ “button”窗口文本,窗口文本,窗口风格,窗口风格,/BS_PUSHBUTTON | WS_CHILD | WS_VISIBLEx位置,位置,y位置,位置,宽度,高度,宽度,高度,父窗口,父窗口,子窗口子窗口ID
23、,程序实例句柄,程序实例句柄,额外参数额外参数)4.1 按钮类按钮类n消息处理消息处理WM_COMMANDwParam(子窗口子窗口ID)4.2 编辑类编辑类n子窗口的创建子窗口的创建CreateWindow(类名,类名,/“edit”窗口文本,窗口文本,窗口风格,窗口风格,/ES_RIGHT|WS_BORDER| WS_CHILD | WS_VISIBLEx位置,位置,y位置,位置,宽度,高度,宽度,高度,父窗口,父窗口,子窗口子窗口ID,程序实例句柄,程序实例句柄,额外参数额外参数)4.2 编辑类编辑类n消息处理消息处理WM_COMMANDwParam(子窗口子窗口ID)给编辑类发送消息给
24、编辑类发送消息nSendMessage(hwnd, WM_SETTEXT, 0,string);获取编辑类文本信息获取编辑类文本信息nGetWindowText(hwnd,buff,len);5. 应用实例:简易计算器的实现表达式求值类#include #include ExpCalc.hstring strExpression;CExpCalc expCalc;expCalc.Compute(strExpression);12.1808123+456-789*0.C/=xy命名12.1808123+456-789*0.C/=xyconst int ID_BTN_NUM0 = 10000;co
25、nst int ID_BTN_NUM1 = 10001;const int ID_BTN_NUM2 = 10002;const int ID_BTN_NUM3 = 10003;const int ID_BTN_NUM4 = 10004;const int ID_BTN_NUM5 = 10005;const int ID_BTN_NUM6 = 10006;const int ID_BTN_NUM7 = 10007;const int ID_BTN_NUM8 = 10008;const int ID_BTN_NUM9 = 10009;const int ID_BTN_OPTR_ADD = 1001
26、0;const int ID_BTN_OPTR_SUB = 10011;const int ID_BTN_OPTR_MUL = 10012;const int ID_BTN_OPTR_DIV = 10013;const int ID_BTN_OPTR_DOT = 10014;const int ID_BTN_OPTR_CLR = 10015;const int ID_BTN_OPTR_EQ = 10016;const int ID_EDIT_RESULT = 10017;布局12.1808123+456-789*0.C/=窗口大小:窗口大小:210*280结果显示(编辑框):结果显示(编辑框)
27、:190*48按钮(按钮(=除外):除外):40*28按钮按钮=尺寸:尺寸:190*28横向间隔:横向间隔:15纵向间隔:纵向间隔:10起始位置:起始位置:(10,10)xy布局12.1808123+456-789*0.C/=WinW=210; WinH=280;EdtW=190; EdtH=48;BtnW=40; BtnH=28;SBtnW=EdtW=190;SpaH=15;SpaW=10;SX=10; SY=10;xy布局12.1808123+456-789*0.C/=POINT EditPos= SX, SY;POINT BtnPos17;BtnPosID_BTN_NUM1-10000.
28、x = SX;BtnPosID_BTN_NUM1-10000.y = SY+EdtH+SpaH;char *BtnCaption=0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+, -, *, /, ., c, =;xy窗口句柄12.1808123+456-789*0.C/=static HWND hwndEdit;static HWND hwndButton17;xy消息处理(1)12.1808123+456-789*0.C/=case WM_CREATE: for(int i=0; i=ID_BTN_NUM0 & wParam=ID_BTN_OPTR_DOT) strExpre
29、ssion.push_back( BtnCaptionwParam-ID_BTN_NUM00); SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)strExpression.c_str(); else if(wParam=ID_BTN_OPTR_CLR) strExpression.clear(); SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)strExpression.c_str(); else if(wParam=ID_BTN_OPTR_EQ) char buff256; GetWindowText(h
30、wndEdit,buff,256); strExpression = buff; expCalc.Compute(strExpression); SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)strExpression.c_str(); xy字体创建HFONT EditFont;EditFont = CreateFont(EdtH, 0.4*EdtH, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH, Arial);SendMessage (hwndEdit, WM_SETFONT, (WPARAM)EditFont, TRUE);12.1808123+456-789*0.C/=y问题?n自定义风格如何实现?自定义风格如何实现?MFCn计算器功能扩展计算器功能扩展?增加括号与存储增加括号与存储容错机制容错机制