要跟计算机进行交互,就需要计算机显示信息给人看到,或者发出声音给人听到,然后人看到或听到相应的信息后,再输入其它信息给计算机,这样就可以让计算机进行数据处理,把结果显示给我们。现在就来编写一个最简单的Windows应用程序,让它提示一行文字给我们看到,这就是简单的目标。
它实现的源程序和界面如下:
上面这个图,是从VC++ 2005里截出来的。这样可以看到源程序和显示的界面,很清楚地知道那些内容在那里显示,显示窗口里的标题是例子,就是MessageBox里的字符串“例子”的显示。“第一个应用程序”也是那样显示出来的。第一个应用程序是非常简单的,下面再来详细地解说每行程序的作用。
源程序如下:
#001 // First.cpp : 应用程序入口文件
#002 //
#003
#004 #include "stdafx.h"
#005 #include "First.h"
#006
#007 //
#008 //第一个例子。
#009 //蔡军生 2007/07/02
#010 //
#011 int APIENTRY _tWinMain(HINSTANCE hInstance,
#012 HINSTANCE hPrevInstance,
#013 LPTSTR lpCmdLine,
#014 int nCmdShow)
#015 {
#016 UNREFERENCED_PARAMETER(hPrevInstance);
#017 UNREFERENCED_PARAMETER(lpCmdLine);
#018 UNREFERENCED_PARAMETER(hInstance);
#019 UNREFERENCED_PARAMETER(nCmdShow);
#020
#021 //获取桌面的句柄。
#022 HWND hWnd = GetDesktopWindow();
#023
#024 //显示一行消息。
#025 ::MessageBox(hWnd, _T("第一个应用程序"), _T("例子"), MB_OK);
#026
#027 //
#028 return 0;
#029 }
第4行是包含Windows的API头文件。在这个文件里包含一些系统的定义等。
第5行是包行C++的头文件。
第11行是定义WinMain的入口。
第16行到第19行是指明不生产这些参数不使用的警告。
第22行是获取桌面的句柄。
第25行是显示一个窗口提示信息。
第28行是返回程序出错码。
从上面这段程序就可以看到,_tWinMain是应用程序的入口函数,这里是使用它的宏,定义在tchar.h头文件里,为什么要这样作宏定义的呢?由于Windows的应用程序要适应UNICODE和以前单字符的应用程序,由于Windows这两个API的定义是不一样的,如下:
UNICODE的定义:
#define _tWinMain wWinMain
单字符的定义:
#define _tWinMain WinMain
只要经过这样的宏定义后,就可以适应不同字符宽度的函数接口了。由于我是采用UNICODE编译的,所以这里使用wWinMain函数定义,下面再把它的定义找出来,如下:
int
WINAPI
wWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nShowCmd
);
这里要详细地解释一下函数wWinMain的参数,它有四个参数。
hInstance是当前应用程序的实例句柄,一般用来区分不同的资源使用。
hPrevInstance是以前Win98使用的句柄,在Win2000以后的操作系统里都是空值NULL。
lpCmdLine是命令行参数,比如你在Windows开始菜单里运行一个程序,并添加参数在后面,就会传递给应用程序,后面再详细讨论。
nShowCmd是窗口的显示方式,比如最大化显示,最小化显示,还是正常显示。
Windows运行程序时,是通过运行库里的启动代码来调用wWinMain函数,它是在启动文件里如下调用:
#ifdef WPRFLAG
mainret = wWinMain(
#else /* WPRFLAG */
mainret = WinMain(
#endif /* WPRFLAG */
(HINSTANCE)&__ImageBase,
NULL,
lpszCommandLine,
StartupInfo.dwFlags & STARTF_USESHOWWINDOW
? StartupInfo.wShowWindow
: SW_SHOWDEFAULT
);
这就是操作系统传递给应用程序的值,现在就来演示使用第一个参数hInstance。
请看下面的例子:
#001 #include "stdafx.h"
#002 #include "First.h"
#003
#004 //
#005 //第一个例子。
#006 //蔡军生 2007/07/03
#007 //
#008 int APIENTRY _tWinMain(HINSTANCE hInstance,
#009 HINSTANCE hPrevInstance,
#010 LPTSTR lpCmdLine,
#011 int nCmdShow)
#012 {
#013 UNREFERENCED_PARAMETER(hPrevInstance);
#014 UNREFERENCED_PARAMETER(lpCmdLine);
#015 UNREFERENCED_PARAMETER(nCmdShow);
#016
#017 //使用应用程序句柄
#018 const int MAXSIZE_APPBUF = 256;
#019 TCHAR wAppTile[MAXSIZE_APPBUF];
#020 LoadString(hInstance,IDS_APP_TITLE,wAppTile,MAXSIZE_APPBUF);
#021
#022 //获取桌面的句柄。
#023 HWND hWnd = GetDesktopWindow();
#024
#025 //显示一行消息。
#026 MessageBox(hWnd, _T("第一个应用程序"), wAppTile, MB_OK);
#027
#028 //
#029 return 0;
#030 }
这个例子是在前面的基础上修改的,主要添加了使用应用程序实例句柄。在第19行里定义了一个保存应用程序标题的缓冲区,然后在第20行里调用函数LoadString从应用程序的资源里加载字符串,它的第一个参数就使用到hInstance句柄。因此应用程序句柄是表示程序在资源上唯一的标识符。
Windows API一日一练(3)使用命令行参数
下面再接着练习使用命令行参数,先在VC2005调试设置里设置输入参数,如下图:
可以看到在Command Arguments里输入给程序传送的命令行参数(cmd1 cmd2 命令行参数)。
接着修改原来的程序如下:
#001 int APIENTRY _tWinMain(HINSTANCE hInstance,
#002 HINSTANCE hPrevInstance,
#003 LPTSTR lpCmdLine,
#004 int nCmdShow)
#005 {
#006 UNREFERENCED_PARAMETER(hPrevInstance);
#007 UNREFERENCED_PARAMETER(nCmdShow);
#008
#009 //使用应用程序句柄
#010 const int MAXSIZE_APPBUF = 256;
#011 TCHAR wAppTile[MAXSIZE_APPBUF];
#012 ::LoadString(hInstance,IDS_APP_TITLE,wAppTile,MAXSIZE_APPBUF);
#013
#014 //获取桌面的句柄。
#015 HWND hWnd = ::GetDesktopWindow();
#016
#017 //显示命令行参数。
#018 ::MessageBox(hWnd, lpCmdLine, wAppTile, MB_OK);
#019
#020
#021 //显示一行消息。
#022 ::MessageBox(hWnd, _T("第一个应用程序"), wAppTile, MB_OK);
#023
#024 //
#025 return 0;
#026 }
#027
在上面的程序里添加了第18行的代码,用来显示程序命令行的参数。它的显示结果如下:
这样就可以看到WinMain两个参数的使用了。现在就使用了第一个API函数WinMain了,就是这么简单地就学会了使用第一个API函数。
Windows API一日一练(4)MessageBox函数
为了显示提示信息给用户,Windows是提供了一个非常方便的API函数MessageBox给用户使用,使用这个API函数可以显示简单的文字信息出来,提醒或提示用户进行下一步操作。
函数声明如下:
WINUSERAPI
int
WINAPI
MessageBoxA(
__in_opt HWND hWnd,
__in_opt LPCSTR lpText,
__in_opt LPCSTR lpCaption,
__in UINT uType);
WINUSERAPI
int
WINAPI
MessageBoxW(
__in_opt HWND hWnd,
__in_opt LPCWSTR lpText,
__in_opt LPCWSTR lpCaption,
__in UINT uType);
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif // !UNICODE
从上面可以看出,Windows的API是两种声明,一种是使用到ANSI编码,一种是使用到UNICODE编码的API函数。通过宏定义把这两种API名称统一到MessageBox的声明。这是一种使用选择不同API的技术,在今后的编程里,大多数都需要使用UNICODE编码了,因为可以适应不同国家的语言显示,可以国际化编程,特别对于中文支持更加需要UNICODE编程。
下面来解释一下参数的定义:
hWnd是指向父窗口的句柄,如果没有父窗口,可以把这个参数设置为NULL。
lpText是需要显示的文字。显示字符串的起始地址。
lpCaption是在窗口上标题显示。
uType是窗口组合按钮和显示图标的类型。后面再详细说明。
返回值是一个整数,如果有取消按钮,并且按下ESC键就返回IDCANCEL。如果有其它按钮,并且按下,就返回相应的值。主要的值如下:
IDABORT 放弃按钮
IDCANCEL取消按钮
IDCONTINUE 继续按钮
IDIGNORE 忽略按钮
IDNO 否按钮
IDOK 确定按钮
IDRETRY 重试按钮
IDTRYAGAIN 重试按钮
IDYES 是按钮
演示例子如下:
上面显示的代码是:
#001 //MB_DEFBUTTON4
#002 int CMsgBox::Show_MB_DEFBUTTON4(void)
#003 {
#004 //显示MB_DEFBUTTON4。
#005 return ::MessageBox(NULL, _T("MB_YESNOCANCEL|MB_DEFBUTTON4|MB_HELP"),
#006 _T("第一个应用程序"), MB_YESNOCANCEL|MB_DEFBUTTON4|MB_HELP|MB_ICONQUESTION);
#007 }
uType常用的选择值如下:
按钮类型:
MB_ABORTRETRYIGNORE
MB_CANCELTRYCONTINUE
MB_HELP
MB_OK
MB_OKCANCEL
MB_RETRYCANCEL
MB_YESNO
MB_YESNOCANCEL
图标类型:
MB_ICONEXCLAMATION
MB_ICONWARNING
MB_ICONINFORMATION
MB_ICONASTERISK
MB_ICONQUESTION
MB_ICONSTOP
MB_ICONERROR
MB_ICONHAND
设置缺省按钮值:
MB_DEFBUTTON1
MB_DEFBUTTON2
MB_DEFBUTTON3
MB_DEFBUTTON4
修改显示信息窗口的属性:
MB_APPLMODAL
MB_SYSTEMMODAL
MB_TASKMODAL
MB_RIGHT
MB_RTLREADING
MB_SETFOREGROUND
MB_TOPMOST
MB_SERVICE_NOTIFICATION
Windows API一日一练(5)RegisterClass和RegisterClassEx函数
为了可以创建自己的窗口,就需要向Windows操作系统注册窗口类型,以便后面创建窗口时调用。当然,如果使用Windows预先注册的窗口是不需要注册的。
函数声明如下:
#if(WINVER >= 0x0400)
WINUSERAPI
ATOM
WINAPI
RegisterClassExA(
__in CONST WNDCLASSEXA *);
WINUSERAPI
ATOM
WINAPI
RegisterClassExW(
__in CONST WNDCLASSEXW *);
#ifdef UNICODE
#define RegisterClassEx RegisterClassExW
#else
#define RegisterClassEx RegisterClassExA
#endif // !UNICODE
函数的输入参数是一个WNDCLASSEXA或WNDCLASSEXW的指针。这里主要介绍UNICODE版本的函数定义,WNDCLASSEXW的结构定义如下:
typedef struct tagWNDCLASSEXW {
UINT cbSize;
/* Win 3.x */
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCWSTR lpszMenuName;
LPCWSTR lpszClassName;
/* Win 4.0 */
HICON hIconSm;
} WNDCLASSEXW, *PWNDCLASSEXW, NEAR *NPWNDCLASSEXW, FAR *LPWNDCLASSEXW;
cbSize是本结构的字节大小,一般设置为sizeof(WNDCLASSEXW);
style是窗口类型。
lpfnWndProc是窗口处理消息的回调函数。
cbClsExtra是窗口类型的扩展。
cbWndExtra是窗口实例的扩展。
hInstance是窗口实例句柄。
hIcon是窗口图标。
hCursor是窗口的光标。
hbrBackground是窗口背景颜色。
lpszMenuName是窗口菜单名称。
lpszClassName是窗口类型的名称。
hIconSm是窗口小图标。
调用这个函数的实例如下:
#001 //
#002 // 函数: MyRegisterClass()
#003 //
#004 // 目的: 注册一个窗口类型.
#005 //
#006 // 蔡军生 2007/07/12
#007 //
#008 ATOM MyRegisterClass(HINSTANCE hInstance)
#009 {
#010 WNDCLASSEX wcex;
#011
#012 wcex.cbSize = sizeof(WNDCLASSEX);
#013
#014 wcex.style = CS_HREDRAW | CS_VREDRAW;
#015 wcex.lpfnWndProc = WndProc;
#016 wcex.cbClsExtra = 0;
#017 wcex.cbWndExtra = 0;
#018 wcex.hInstance = hInstance;
#019 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TESTWIN));
#020 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
#021 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
#022 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TESTWIN);
#023 wcex.lpszClassName = szWindowClass;
#024 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
#025
#026 return RegisterClassEx(&wcex);
#027 }
第10行定义一个窗口结构的对象wcex。
第12行设置窗口结构的大小。
第14行设置窗口类型。
第15行设置窗口消息处理函数WndProc。
第16行设置窗口类型的扩展为空。
第17行设置窗口实例的扩展为空。
第18行设置窗口当前实例句柄hInstance。
第19行设置窗口图标。
第20行设置光标为箭头。
第21行设置窗口背景颜色为白色。
第22行设置窗口菜单。
第23行设置窗口类型名称。
第24行设置窗口小图标。
第26行是调用函数RegisterClassEx注册这个窗口类型。
如果注册成功,返回这个窗口类型的标识号,可以用标识号进行创建窗口,查找窗口和注销窗口类型等等。如果失败返回的值是空,因此可以通过检查返回值为判断是否调用成功。
from: http://blog.csdn.net/caimouse/article/category/49656/6
0 0