实习指导书1Windows消息循环机制及API程序设计.docx
- 文档编号:22806181
- 上传时间:2023-04-28
- 格式:DOCX
- 页数:24
- 大小:985.78KB
实习指导书1Windows消息循环机制及API程序设计.docx
《实习指导书1Windows消息循环机制及API程序设计.docx》由会员分享,可在线阅读,更多相关《实习指导书1Windows消息循环机制及API程序设计.docx(24页珍藏版)》请在冰豆网上搜索。
实习指导书1Windows消息循环机制及API程序设计
第一部分Windows消息循环机制
及API程序设计
1概述
1.1操作系统及窗口环境
操作系统(OperatingSystem,简称OS)传统上是负责对计算机硬件直接控制及管理的系统软件。
操作系统的功能一般包括处理器管理、存储管理、文件管理、设备管理和作业管理等。
当多个程序同时运行时,操作系统负责规划以优化每个程序的处理时间。
一个操作系统可以在概念上分割成两部分:
内核(Kernel)以及壳(shell)。
一个壳程序包裹了与硬件直接交流的内核:
在有些操作系统上内核与壳完全分开(例如Unix、Linux等),这样用户就可以在一个内核上使用不同的壳;而另一些的内核与壳关系紧密(例如MicrosoftWindows),内核及壳只是操作层次上不同而已。
MicrosoftWindows提供了一系列的API函数调用内核及壳的相关功能,这也是普通用户访问系统功能的唯一方式,其它复杂的框架开发环境,例如MFC,都是在此基础上实现的。
1.2消息循环机制
Windows是一个多进程的图形窗口操作系统,Windows应用程序与DOS应用程序有很大的区别。
DOS应用程序采用顺序执行过程,而Windows是一个基于事件的消息(Message)驱动系统。
Windows应用程序是按照“事件→消息→处理”非顺序的机制运行。
当有某个事件(如单击鼠标、键盘输入和执行菜单命令等)发生时,Windows会根据具体的事件产生对应的消息,并发送到指定应用程序的消息队列;应用程序从消息队列中取出消息,并根据不同的消息进行不同的处理。
1.3内容及目的
实践之前首先要充分理解Windows的消息循环机制,了解Windows的API函数族的分类及大致功能,并在此基础上了解基本WindowsAPI方式开发的窗口程序的基本过程。
该实践的目的并不在于学会如何利用WindowsAPI开发窗口程序,而是要求同学们了解并掌握如下事实:
任何框架开发环境归根结底都是对WindowsAPI函数的封装与调用!
在利用一个框架环境开发Windows程序的过程中,应该明白所使用的框架模块调用了WindowsAPI中的那些功能函数。
作为练习,本次实践要求同学们完成如下任务:
用visualC++开发一个Win32窗口程序,并实现如下功能:
●实现菜单功能;
●点击某两个菜单可在主窗口中显示或清除文字(文字内容不做要求);
●点击某个菜单可弹出一个自定义的对话框(对话框中的元素不做要求),单击对话框中的“确定”或“取消”按钮,可结束对话框。
1.4实践环境要求
开发环境统一使用MicrosoftVisualStudio2005。
2创建基本工程步骤
1.打开MicrosoftVisualStudio2005开发环境;
2.选择“新建”项目
3.弹出新建项目对话框,在项目类型中依次选择:
VisualC++->Win32,在右面的模板中选:
Win32项目,在下面的名称中,键入项目名称,这里是:
Task1,然后在位置一栏中选择项目保存的路径。
如果未勾选“创建解决方案的目录”选项,项目路径中的文件内容如下:
如果勾选“创建解决方案的目录”选项,则会在项目路径中以“解决方案名称”创建子目录,并在该目录下放置工程文件和源代码文件。
下图是解决方案目录的内容:
下图是解决方案目录中Task1子目录的内容:
4.在确定新建对话框中的内容设置好后,选择确定按钮,弹出向导:
5.单击“下一步”按钮,选择Windows应用程序选项,其它都不选,按“完成”创建项目。
6.在项目解决方案资源管理器中应包含下图中的文件:
7.单击菜单中的“项目->属性”,弹出属性页对话框:
在对话框中的左侧列表中选择“配置属性->常规”,在右侧的“项目默认值->字符集”中选择“使用多字节字符集”,按确认更改项目属性。
(为什么要这样?
请大家课后自行学习关于UNICODE的相关知识以及在Win32环境下操作UNICODE字符串的相关函数)
8.单击“启动调试”按钮,在弹出的对话框中选择“是”,运行程序:
运行结果如下:
至此,基本框架代码已经由环境建立,下一步可以编写自己的代码到框架中并实现预期的功能,具体参见下一节的主要函数及关键代码解析。
3主要函数及关键代码解析
由框架代码生成的函数主要有如下几个(有些不熟悉的类型一般都是宏定义,在开发环境中将鼠标光标停留在上面可即时显示其实际的定义):
1.程序入口函数,相当于c/c++中的main函数,在win32环境下为WinMain函数:
intAPIENTRY_tWinMain(HINSTANCEhInstance,
HINSTANCEhPrevInstance,
LPTSTRlpCmdLine,
intnCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
//TODO:
在此放置代码。
MSGmsg;
HACCELhAccelTable;
//初始化全局字符串,从程序资源中将相应的字符串写入全局字符串变量中
LoadString(hInstance,IDS_APP_TITLE,szTitle,MAX_LOADSTRING);
LoadString(hInstance,IDC_TASK1,szWindowClass,MAX_LOADSTRING);
MyRegisterClass(hInstance);
//执行应用程序初始化:
if(!
InitInstance(hInstance,nCmdShow))
{
returnFALSE;
}
hAccelTable=LoadAccelerators(hInstance,MAKEINTRESOURCE(IDC_TASK1));
//主消息循环:
while(GetMessage(&msg,NULL,0,0))
{
if(!
TranslateAccelerator(msg.hwnd,hAccelTable,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return(int)msg.wParam;
}
_tWinMain是一个宏,在多字节字符环境下就是WinMain,在UNICODE环境下是wWinMain。
主消息循环部分不断从消息队列中获取消息,并翻译转换后派发出去,调用相应的消息例程。
2.注册窗口类函数,用于确定主窗口显示过程中的一些图形内容、风格,处理函数等:
ATOMMyRegisterClass(HINSTANCEhInstance)
{
WNDCLASSEXwcex;
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.style=CS_HREDRAW|CS_VREDRAW;
wcex.lpfnWndProc=WndProc;//主窗口消息处理函数
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=hInstance;
wcex.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_TASK1));
wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName=MAKEINTRESOURCE(IDC_TASK1);
wcex.lpszClassName=szWindowClass;
wcex.hIconSm=LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_SMALL));
returnRegisterClassEx(&wcex);
}
3.创建主窗口
BOOLInitInstance(HINSTANCEhInstance,intnCmdShow)
{
HWNDhWnd;
hInst=hInstance;//将实例句柄存储在全局变量中
hWnd=CreateWindow(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);
if(!
hWnd)
{
returnFALSE;
}
//显示主窗口并绘制
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
returnTRUE;
}
4.主窗口消息函数,API风格的开发这个函数就是一个大的嵌套的switch-case结构,用于调用不同消息所对应的处理函数。
例如,WM_COMMAND用于处理用户发出的命令,如果其子ID为IDM_ABOUT,就表明用户单击了about菜单项,则调用about对话框函数。
LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam)
{
intwmId,wmEvent;
PAINTSTRUCTps;
HDChdc;
switch(message)
{
caseWM_COMMAND:
wmId=LOWORD(wParam);
wmEvent=HIWORD(wParam);
//分析菜单选择:
switch(wmId)
{
caseIDM_ABOUT:
DialogBox(hInst,MAKEINTRESOURCE(IDD_ABOUTBOX),hWnd,About);
break;
caseIDM_EXIT:
DestroyWindow(hWnd);
break;
default:
returnDefWindowProc(hWnd,message,wParam,lParam);
}
break;
caseWM_PAINT:
hdc=BeginPaint(hWnd,&ps);
//TODO:
在此添加任意绘图代码...
EndPaint(hWnd,&ps);
break;
caseWM_DESTROY:
PostQuitMessage(0);
break;
default:
returnDefWindowProc(hWnd,message,wParam,lParam);
}
return0;
}
5.About对话框消息函数。
任何一个独立的窗口都有自己的消息循环处理函数,对话框也是一个窗口,也需要独立的处理函数,用于处理用户与对话框中个元素的交互动作等。
例如,下述代码中,用户如果点击了“确定”“取消”按钮,则激发WM_COMMAND消息,该消息数据中的wParam参数中包含了对应“确定”按钮的IDOK和对应“取消”按钮的IDCANCEL值,用户经过判断,可调用EndDialog函数结束对话框。
INT_PTRCALLBACKAbout(HWNDhDlg,UINTmessage,WPARAMwParam,LPARAMlParam)
{
UNREFERENCED_PARAMETER(lParam);
switch(message)
{
caseWM_INITDIALOG:
return(INT_PTR)TRUE;
caseWM_COMMAND:
if(LOWORD(wParam)==IDOK||LOWORD(wParam)==IDCANCEL)
{
EndDialog(hDlg,LOWORD(wParam));
return(INT_PTR)TRUE;
}
break;
}
return(INT_PTR)FALSE;
}
在资源视图中,可通过双击Dialog文件夹中的IDD_ABOUTBOX对话框打开设计视图,编辑对话框中的元素:
在设计视图中,右键单击相应对话框元素并在弹出菜单中选择“属性”,可修改对应元素的属性值,例如,“确定”按钮的ID属性默认为“IDOK”,用户可自行修改该值(当然,一些系统默认的值不推荐修改,而对于用户自定义的一些元素,例如新加入的自定义按钮等,其属性值一般为开发环境根据规则自动生成的,开发人员应根据用途适当修改属性值,以便于开发过程中的阅读和记忆)。
4开发新功能
1.新建菜单项目
在资源视图中打开Menu文件夹,双击IDC_Task1项目,打开菜单编辑窗口:
新建跟菜单项目和下拉菜单项目,如上图,并编辑下拉菜单项目的属性:
2.在资源视图中的Dialog文件夹上单击右键,在弹出菜单中选择“插入Dialog”:
3.修改新建的对话框资源属性,例如,可将其ID修改为IDD_MYDIALOG,在实际开发中可根据其作用,赋一个有意义的ID标识,其它属性可酌情修改:
4.在对话框编辑器中打开刚刚创建的对话框,在其中新建一个编辑框(EditControl),并将编辑框的ID调整为IDC_MESSAGE,该ID会在更新或获取编辑框中文字内容的API函数中用到:
新建的对话框一般会默认存在确认和取消按钮,保留其默认属性即可。
5.编辑代码
●修改全局变量和函数声明如下:
//GlobalVariables:
HINSTANCEhInst;//currentinstance
TCHARszTitle[MAX_LOADSTRING];//Thetitlebartext
TCHARszWindowClass[MAX_LOADSTRING];//Thetitlebartext
TCHARszHello[MAX_LOADSTRING];
BOOLbShow=true;
//Fowarddeclarationsoffunctionsincludedinthiscodemodule:
ATOMMyRegisterClass(HINSTANCEhInstance);
BOOLInitInstance(HINSTANCE,int);
LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);
LRESULTCALLBACKAbout(HWND,UINT,WPARAM,LPARAM);
LRESULTCALLBACKMyDialog(HWND,UINT,WPARAM,LPARAM);
●在task1.cpp文件的末尾添加MyDialog函数:
//MesagehandlerforMyDialog.
LRESULTCALLBACKMyDialog(HWNDhDlg,UINTmessage,WPARAMwParam,LPARAMlParam)
{
switch(message)
{
caseWM_INITDIALOG:
returnTRUE;
caseWM_COMMAND:
if(LOWORD(wParam)==IDOK||LOWORD(wParam)==IDCANCEL)
{
:
:
GetDlgItemText(hDlg,IDC_MESSAGE,szHello,MAX_LOADSTRING);
EndDialog(hDlg,LOWORD(wParam));
:
:
InvalidateRect(:
:
GetParent(hDlg),NULL,1);
returnTRUE;
}
break;
}
returnFALSE;
}
MyDialog函数可拷贝About函数,并修改函数名和相应内容即可。
●修改主窗口消息映射函数中的switch-case部分如下所示:
switch(message)
{
caseWM_COMMAND:
wmId=LOWORD(wParam);
wmEvent=HIWORD(wParam);
//Parsethemenuselections:
switch(wmId)
{
caseIDM_ABOUT:
DialogBox(hInst,(LPCTSTR)IDD_ABOUTBOX,hWnd,(DLGPROC)About);
break;
caseIDM_EXIT:
DestroyWindow(hWnd);
break;
caseIDM_MYDLG:
DialogBox(hInst,(LPCTSTR)IDD_MYDIALOG,hWnd,(DLGPROC)MyDialog);
break;
caseIDM_SHOW:
bShow=true;
:
:
InvalidateRect(hWnd,NULL,1);
CheckMenuItem(:
:
GetMenu(hWnd),IDM_SHOW,MF_CHECKED);
CheckMenuItem(:
:
GetMenu(hWnd),IDM_ERASE,MF_UNCHECKED);
break;
caseIDM_ERASE:
bShow=false;
:
:
InvalidateRect(hWnd,NULL,1);
CheckMenuItem(:
:
GetMenu(hWnd),IDM_SHOW,MF_UNCHECKED);
CheckMenuItem(:
:
GetMenu(hWnd),IDM_ERASE,MF_CHECKED);
break;
default:
returnDefWindowProc(hWnd,message,wParam,lParam);
}
break;
caseWM_PAINT:
hdc=BeginPaint(hWnd,&ps);
//TODO:
Addanydrawingcodehere...
if(bShow)
{
RECTrt;
GetClientRect(hWnd,&rt);
DrawText(hdc,szHello,strlen(szHello),&rt,DT_TOP);
}
EndPaint(hWnd,&ps);
break;
caseWM_DESTROY:
PostQuitMessage(0);
break;
default:
returnDefWindowProc(hWnd,message,wParam,lParam);
}
●编译并运行
5总结及要求
除了了解操作系统相关的知识以及消息循环以外,学生在课余时间应该通览Win32API函数相关资料,这一过程不在于是否记住API函数的详细信息,而是要了解API函数的分类、大致作用、命名规则、参数规律等,便于在开发过程中更好的利用帮助文档MSDN。
通过本实践环节,学生应该能够熟练应用开发环境,了解基本操作,并能对IDE(IntegratedDevelopmentEnvironment的简称)能够做出简单调整,符合自己的开发习惯。
学生应该能够熟练使用这些API函数:
●CheckMenuItem
●DrawText
●DialogBox
●InvalidateRect
●GetDlgItemText
●另外,学生应该通过在MSDN中学习上述函数,了解并学习与其相近的一些函数。
例如,学习了GetDlgItemText,应该知道SetDlgItemText怎么用,并进一步知道Get/SetDlgItemInt如何使用,这些相关的内容在MSDN中都有相关联的链接存在。
6参考资料
Win32API大全
Windows操作系统
7实践内容提交
关键代码打包并Email至:
stzhou.cpp@
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实习 指导书 Windows 消息 循环 机制 API 程序设计
![提示](https://static.bdocx.com/images/bang_tan.gif)