《windows 程序设计》读书笔记 一

 

目录

基础知识

主要的动态链接库:

API 及内存管理模式:

第一个 Windows 程序解析:

头文件:

Windows 程序的入口:

MessageBox 函数:


基础知识

主要的动态链接库:

早期 Windows 的大部分只是实现了 3 个动态链接库。它们分别代表了 Windows 的 3 个主要的子系统,即内核 (kernel)、用户 (user) 以及 GDI。虽然新版 Windows 中子系统增加了不少undefined 但是通常 Windows 程序调用的大部分函数实际上仍然以这 3 个模块为主。

内核 (在 16 位的 KRNL386.exe 及 32 位的 KERNEL32.DLL 中实现) 负责操作系统的那些传统工作,包括内存管理、文件输入/输出及任务管理等。

用户 (在 16 位的 User.exe 及 32 位的 User32.DLL 中实现) 指的是用户界面,负责所有的窗口管理。

GDI (在 16 位的 GDI.exe 及 32 位的 GDI32.DLL 中实现)就是图形设备接口,负责在屏幕或打印机上显示文本与图形。

当 Windows 程序运行时,它通过一个叫做 “动态链接” (dynamic linking) 的进程与 Windows 接口。每个 Windows 的 EXE 文件包含它所要用的各个动态链接库以及库中的函数的引用地址 (referenee) 。当一个 Windows 程序被装入内存之后,程序中的函数调用都被解析成 DLL 函数入口的指针,同时这些被调用的函数也被装入内存 (如果还没有在内存中的话)。

API 及内存管理模式:

大约是在当体系结构从 16 位变到 32 位的时候,Windows API 及其语法发生了最大改变。从1.0 版到 3.1 版,Windows 一直采用 16 位的英特尔 8086、8088 及 286 微处理器的所谓分段内存管理模式 (Segmented Memory Model,SMM)。

为了保证兼容性,英特尔 386 之后的 32 位微处理器也都支持这一模式,在这种模式下,微处理器的寄存器 (Register) 宽度为 16 位,因此 C 的 int 数据类型也是 16 位宽。在分段内存管理模式下,内存地址由两部分组成,一个 16 位的段 (Segment) 指针和一个 16 位的位移 (Offseb) 指针。从程序员角度来看,这种方式相当繁杂,需要区分长、短指针。长指针包括一个段地址和一个位移地址,而短指针则仅仅包括在约定的段地址下的一个位移地址。

从 Windows NT 及 Windows 95 开始,利用 32 位英特尔 386、486 以及奔腾处理器, Windows 开始支持 32 位的平面内存管理模式。C 的 int 数据类型也因此扩展成 32 位宽。为 32 位 Windows 编写的程序可以直接用 32 位的指针访问平面线性内存空间。

第一个 Windows 程序解析:

C 字符模式和对应 Windows 程序:

#include<stdio.h>
mian()
{
    printf("helloundefinedworld\n");
}

在 Visual C++ Deceloper Studio 中创建对应 Windows 程序及编译运行:

首先从 File 菜单下选择 Newundefined 在 New 的对话框里选择 Project 选项卡。选中 Win32 Application。在 Location 栏里选择一个子目录。在 Project Name 字段中键入项目名,在本例中即 HelloMsg。这也将成为 Location 栏中所显示目录的子目录。这时 Create New Werkspace 按钮应该已经被选中,Platforms 部分应该显示为 Win32。单击 OK。

这时候会出现一个标题为 Win32 Application - Step 1 of 1 的对话杠。选择 An empty projeet 表示你想建立一个空项目,然后单击 Finish 按钮。

再次从 File 菜单下选择 New 选项,在 New 对话框里选择 Files 选项卡,选中 C++ Source File,这时 Add to Project 复选框应该已经被选中,并提示 HelloMsg。 在 File 框中输入 HelloMsg.c,然后单击 OK 。

编译、链接及运行:

当你准备好编译 HELLOMSG 程序时,你可以从 Build 菜单中选择 Build Hellomsg.exe,或按 F7 键,还可以从 Build 工具档里 (选择 Build) 图标。(这一图标的样子会在 Build 菜单中显示。如果 Build 工具栏当时没有显示,你可以从 Tools 菜单下选择 Customize 选项,然后选择 Toolbars 选项卡,选中 Build 或者 Build MiniBar。)

作为另外一种选择undefined 你可以从 Build 菜单下选择 Execute Hellomsg.exe,或者按 Ctrl+F5 键,或者单击 Build 工具栏上的 Execute Program 图标 (这个图标看上去有点像个红色的惊叹号)。你将得到一个消息框,询问你是否要生成该程序。

通常情况下在编译阶段,编译器从 C 源代码文件产生一个.OBJ (目标)文件,在链接阶段,链接器又把 .OBJ 文件和 .LIB(库程序) 文件放到一起产生undefinedEXE (可执行)文件,你可以通过选择 Project 菜单下的 Settings,并单击 Link 标签来查看这些库程序的文件列表。特别要注意的是 KERNEL32.LIB、USER32.LIB 和 GDI32.LIB 三个重要库程序,它们分别代表个主要的 Windows 子系统。它们包含动态链接库的名字,以及与.EXE 相关的访问信息。

Windows 利用这些信息来解析程序中对 KERNEL32.DLL、USER32.DLL 和 GDI32.DLL 动态链接库内的函数的调用。

输入程序如下:

#include <windows.h>
int WINAPI WinMain (HINSTANCE hInstanceundefined HINSTANCE hPrevInstanceundefined
                    PSTR szCmdLineundefined int iCmdShow)
{
     MessageBox (NULLundefined TEXT ("Helloundefined Windows 98!")undefined TEXT ("HelloMsg")undefined 0) ;


     return 0 ;
}

头文件:

#include<windows.h> 是几乎所有用 C 语言编写的 Windows 程序中都有的预处理器指令。

WINDOWS.H 是一个最重要的包含文件,它囊括了若干其他 Windows 头文件,其中的某些头文件又包含另外的一些头文件。

下列几个是最重要也是最基本的头文件:

  • WINDEF.H 基本数据类型定义

  • WINNT.H 支持 Unicode 的类型

  • WINBASE.H 内核函数

  • WINUSER.H 用户界面函数

  • WINGDI.H 图形设备接口函数

这些头文件定义了 Windows 的所有数据类型、函数调用、数据结构以及常量标识符。

Windows 程序的入口:

Windows 程序的入口是 WinMain:

int WINAPI WinMain (HINSTANCE hInstanceundefined HINSTANCE hPrevInstanceundefined PSTR szCmdLineundefined int iCmdShow);

在 WINBASE.H 中声明如下:

int WINAPI WinMain (HINSTANCE hInstanceundefined HINSTANCE hPrevInstanceundefined LPSTR lpCmdLineundefined int nShowCmd );

参数改动:

第三个参数类型从 LPSTR 改为 PSTR,这两种数据类型都在 WINNT.H 中声明为指向字符串的指针,LP 代表长指针(Long Pointer) 属于 16 位系统的产物。参数名从 szCmdLine 变成 IpCmdLine 采用 ”匈牙利标记法“ i 前缀表示 int ,sz前缀标识 "以零结尾的空字符串" (String Terminated with a Zero)

返回值 WINAPI:

WinMain 函数的返回值被定义为 int,WINDEF.H 中定义 WINAPI 为 #define WINNPI _stdcall

各个参数:

WinMain 的第一个参数一般叫做 “实例句柄” (Instance Handle)。在 Windows 程序中,句柄无非就是一个数值,程序里用它来标识某些东西。比如在我们这个例子里,这个句柄就唯一标识了我们的这个程序实际上在某些 Windows 程序中,把句柄当作调用参数是须的。比如在早期的 Windows 版本中,当多路并发运行同一个程序时,就需要为那个程序创建多个实例。同一程序的所有的实例都共享代码以及只读存储(即菜单或对话框模板之类的资源)

个程序可以通过查看 hPrevInstance 参数从而知道是否有它的其他实例正在运行。它也就可以因此跳过某些零散杂务步骤,把一些数据从前一个实例搬到自己的数据区来。

在 32 位 Windows 中,这一概念已不再采用。因此 WinMain 的第二个参数通常总是 NULL (定义为 0 )。

WinMain 的第三个参数是用来运行程序的命令行(Command Line)。有些 Windows 程序在启动时用它来把文件装入内存。

WinMain 的第四个参数用来指明程序最初如何显示,或正常显示,或最大化到全屏,或最小化显示在任务栏上。在第 3 章里会讲到这一参数的使用。

MessageBox 函数:

MessageBox 函数是用来显示短信息的,MessageBox 所显示的小小窗口实际上也是一个对话框。

  • 第一个参数通常是一个窗口句柄(第三章会讲)。

  • 第二个参数就是将要在信息框里出现的文本字符串。

  • 第三个参数是将要在标题栏上显示的文本字符串。

在 HELLOMSG.C 中,这些文本串都被打包在 TEXT 宏代码(Macro)里面。一般来说,并不需要把所有的字符申都打包到 TEXT 宏代码里面,这里之所以这样做是因为这样在把程序转换成 Unicode 时会方便很多。

  • 第四个参数是以前缀 MB_ 打头的一些常量的组合undefined WINUSER.H 中定义了这些相关常量。

现代微软文档:

MessageBox (winuser.h)

显示一个模式对话框,其中包含一个系统图标、一组按钮和一条特定于应用程序的简短消息,例如状态或错误信息。消息框返回一个整数值,指示用户单击了哪个按钮。

语法:

int MessageBox(

[inundefined optional] HWND hWndundefined

[inundefined optional] LPCTSTR lpTextundefined

[inundefined optional] LPCTSTR lpCaptionundefined

[in] UINT uType

);

参数:

[inundefined optional] hWnd

类型:HWND

要创建的消息框的所有者窗口的句柄。如果此参数为NULL,则消息框没有所有者窗口。

[inundefined optional] lpText

类型:LPCTSTR

要显示的消息。如果字符串由多行组成,您可以在每行之间使用回车符和/或换行符分隔各行。

[inundefined optional] lpCaption

类型:LPCTSTR

对话框标题。如果此参数为NULL,则默认标题为Error。

[in] uType

类型:UINT

对话框的内容和行为。此参数可以是来自以下标志组的标志的组合

要指示消息框中显示的按钮,请指定以下值之一:

Value

Meaning

MB_ABORTRETRYIGNORE

0x00000002L

The message box contains three push buttons: Abortundefined Retryundefined and Ignore.

MB_CANCELTRYCONTINUE

0x00000006L

The message box contains three push buttons: Cancelundefined Try Againundefined Continue. Use this message box type instead of MB_ABORTRETRYIGNORE.

MB_HELP

0x00004000L

Adds a Help button to the message box. When the user clicks the Help button or presses F1undefined the system sends a WM_HELP message to the owner.

MB_OK

0x00000000L

The message box contains one push button: OK. This is the default.

MB_OKCANCEL

0x00000001L

The message box contains two push buttons: OK and Cancel.

MB_RETRYCANCEL

0x00000005L

The message box contains two push buttons: Retry and Cancel.

MB_YESNO

0x00000004L

The message box contains two push buttons: Yes and No.

MB_YESNOCANCEL

0x00000003L

The message box contains three push buttons: Yesundefined Noundefined and Cancel.

可以使用 C 中的 OR(|) 按钮把上述某个按钮设置为默认按钮:( MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2

Value

Meaning

MB_DEFBUTTON1

0x00000000L

The first button is the default button.MB_DEFBUTTON1 is the default unless MB_DEFBUTTON2undefined MB_DEFBUTTON3undefined or MB_DEFBUTTON4 is specified.

MB_DEFBUTTON2

0x00000100L

The second button is the default button.

MB_DEFBUTTON3

0x00000200L

The third button is the default button.

MB_DEFBUTTON4

0x00000300L

The fourth button is the default button.

要在消息框中显示图标,请指定以下值之一:

Value

Meaning

MB_ICONEXCLAMATION

0x00000030L

An exclamation-point icon appears in the message box.

MB_ICONWARNING

0x00000030L

An exclamation-point icon appears in the message box.

MB_ICONINFORMATION

0x00000040L

An icon consisting of a lowercase letter i in a circle appears in the message box.

MB_ICONASTERISK

0x00000040L

An icon consisting of a lowercase letter i in a circle appears in the message box.

MB_ICONQUESTION

0x00000020L

A question-mark icon appears in the message box. The question-mark message icon is no longer recommended because it does not clearly represent a specific type of message and because the phrasing of a message as a question could apply to any message type. In additionundefined users can confuse the message symbol question mark with Help information. Thereforeundefined do not use this question mark message symbol in your message boxes. The system continues to support its inclusion only for backward compatibility.

MB_ICONSTOP

0x00000010L

A stop-sign icon appears in the message box.

MB_ICONERROR

0x00000010L

A stop-sign icon appears in the message box.

MB_ICONHAND

0x00000010L

A stop-sign icon appears in the message box.

这些图标当中,有些还另有别名:

#define MB_ICONWARNING MB_ICONEXCLAMATION

#define MB_ICONERROR MB_ICONHAND

#define MB_ICONINFORMATION MB_ICONASTERISK

#define MB_ICONSTOP MB_ICONHAND

返回值:

如果消息框有一个 Cancel 按钮,如果按下 ESC 键或选择了 Cancel 按钮,该函数将返回 IDCANCEL值。如果消息框没有 Cancel 按钮,则按 ESC 将无效,除非存在 MB_OK 按钮。如果显示 MB_OK 按钮并且用户按下 ESC,则返回值将是IDOK。

Return code/value

Description

IDABORT

3

The Abort button was selected.

IDCANCEL

2

The Cancel button was selected.

IDCONTINUE

11

The Continue button was selected.

IDIGNORE

5

The Ignore button was selected.

IDNO

7

The No button was selected.

IDOK

1

The OK button was selected.

IDRETRY

4

The Retry button was selected.

IDTRYAGAIN

10

The Try Again button was selected.

IDYES

6

The Yes button was selected.

通过将 uType 参数设置为相应的标志值,可以在消息框中使用以下系统图标:

官方例子:

在以下示例中,应用程序显示一个消息框,在发生错误情况后提示用户执行操作。

由用户自定义描述错误情况和解决方法的消息,MB_CANCELTRYCONTINUE 样式指示 MessageBox 提供三个按钮,用户可以使用这些按钮选择如何继续。

MB_DEFBUTTON2 样式将默认选择设置在消息框的第二个按钮上,在本例中为 “try again” 按钮。

int DisplayResourceNAMessageBox()
{
    int msgboxID = MessageBox(
        NULLundefined
        (LPCWSTR)L"Resource not available\nDo you want to try again?"undefined
        (LPCWSTR)L"Account Details"undefined
        MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2
    );


    switch (msgboxID)
    {
    case IDCANCEL:
        // TODO: add code
        break;
    case IDTRYAGAIN:
        // TODO: add code
        break;
    case IDCONTINUE:
        // TODO: add code
        break;
    }


    return msgboxID;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沐一 · 林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值