Windows API一日一练(一)第一个应用程序 使用应用程序句柄 使用命令行参数 MessageBox函数 RegisterClass和RegisterClassEx函数

来源:互联网 发布:pdf文件修改软件 编辑:程序博客网 时间:2024/06/08 19:11

要跟计算机进行交互,就需要计算机显示信息给人看到,或者发出声音给人听到,然后人看到或听到相应的信息后,再输入其它信息给计算机,这样就可以让计算机进行数据处理,把结果显示给我们。现在就来编写一个最简单的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行是包含WindowsAPI头文件。在这个文件里包含一些系统的定义等。

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
从上面可以看出,WindowsAPI是两种声明,一种是使用到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
 
函数的输入参数是一个WNDCLASSEXAWNDCLASSEXW的指针。这里主要介绍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