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

2023-05-16

 

目录

基础知识

主要的动态链接库:

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;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《windows 程序设计》读书笔记 一 的相关文章

随机推荐

  • MATLAB:执行程序时调用bin文件夹下的.m文件,却显示找不到该文件

    在运行程序时 xff0c 明明要被调用的函数脚本就在当前文件夹bin 下面 xff0c 但是程序出错找不到对应的文件 xff0c 经过查询发现 xff1a 在命令行窗口输入 xff1a rehash toolboxcache 即可
  • 什么是定时器计数器

    定时器 计数器实际就是加1计数器 1 定时器和计数器的区别 xff1a 区别很小 xff0c 本质上都是计数器 xff0c 但定时器只是计数固定周期的脉冲 xff0c 所以根据频率可以计算出准确的时间 定时器模式 xff1a 对内部机器周期
  • 面试中问到动态库和静态库相关知识

    1 动态库相比较于静态库的优缺点 xff1f 动态库优点 xff1a 节省内存和代码重用 xff0c 当应用程序使用动态链接库时 xff0c 多个应用程序可以共享磁盘上的DLL xff08 windows xff09 和so linux 副
  • 【c++语法大全】

    C 43 43 基础入门 xff08 转载自黑马程序员 xff09 1 C 43 43 初识 1 1 第一个C 43 43 程序 编写一个C 43 43 程序总共分为4个步骤 创建项目创建文件编写代码运行程序 1 1 1 创建项目 Visu
  • Ubuntu20.04 USB网卡驱动安装 - MT7601u

    型号 xff1a TL WN725N 1 0 免驱版 芯片 xff1a MT7601u 具体型号可使用 96 lsusb 96 命令查看 确认型号为mt7601u后 执行如下命令 sudo apt install git build ess
  • 【浅谈插入排序】

    浅谈插入排序 插入排序 xff0c 是把无序数列中的数一个个插入到有序数列中 xff0c 直到无序数列没有数为止 比如有这么一个数列 xff1a 2 4 6 1 3 5 14 2 0 10 一共有10个数 xff0c 我们可以把第一个数当做
  • Meta Learning(元学习)详解

    元学习 概述基本概念基本分类 基本流程模型结构 概述 元学习 xff08 Meta Learing xff09 的提出是针对传统神经网络 模型的泛化性能不足 对信种类任务适应性较差的特点 主要表现为通过少量的计算和新训练数即可用于模型上实现
  • 2022 *CTF REVERSE 的 NaCl

    2022 CTF REVERSE 的 NaCl 下载附件 xff1a 照例扔入 exeinfope 中查看信息 xff1a 照例扔入虚拟机中运行一下 xff0c 查看主要回显信息 xff1a 照例扔入 IDA64 中查看伪代码 xff0c
  • python编码问题的一点笔记

    Python编码 xff1a 中文乱码问题 xff1a 如果开头不声明保存编码的格式是什么 xff0c 那么它会默认使用 ASCII 码保存文件 这时如果你的代码中有中文就会出错了 xff0c 即使你的中文是包含在注释里面的 声明中文编码格
  • 对 IDA 结构体操作的一些理解

    对 IDA 结构体操作的一些理解 前言 xff1a 刚学逆向时把 IDA pro 权威指南过了一遍 xff0c 但读得并不是很细 xff0c 满足日常使用还是没问题的 xff0c 但是对于一些细节的操作或提高效率的方法倒是没能掌握 比如 I
  • 第二届广东省大学生网络攻防大赛 pyre

    第二届广东省大学生网络攻防大赛 pyre 以前做过 pyc 逆向 xff0c 直接的 python exe 逆向还是第一次 xff1a 第一种方法 xff1a 用 pyinstxtractor py 将 exe 文件转换成 pyc 文件 用
  • 2022 年网刃杯 ez_algorithm

    2022 年网刃杯 ez algorithm 下载附件 xff1a 照例扔入 exeinfope 中查看信息 xff0c 64 位无壳 xff1a 照例运行一下 xff0c 查看主要回显信息 xff1a 照例扔入 IDA64 中查看伪代码
  • Base-N 算法加密解密实现:

    目录 Base N 算法加密解密实现 xff1a Base64 加密解密 xff1a xff08 C 语言 python xff09 Base32 加密解密 xff1a xff08 C 语言 xff09 Base N 算法加密解密实现 xf
  • 第二届广东省大学生网络攻防大赛 simple_re

    第二届广东省大学生网络攻防大赛 simple re 流程总结 xff1a xff08 思路原文出自 JANlittle 师傅 xff09 程序将关键函数以对象元素的形式存在对象里 xff0c 然后在申请内存中搭配指针间接调用 xff0c 关
  • 解析 DES 加密算法(C语言):

    目录 解析 DES 加密算法 C语言 xff1a DES 简介 xff1a DES 算法整体流程 xff1a DES 解密 xff1a C 语言代码实现加密解密逻辑 xff1a 解析 DES 加密算法 C语言 xff1a 内容修改自博客 x
  • x64dbg 基本使用技巧

    x64dbg 基本使用技巧 最近使用 DBG 多了起来 xff0c 所以查了一些资料来学习并整理成自适应的笔记 本文摘抄自 xff1a x64dbg 使用技巧与实用插件合集 官方网站 xff1a https x64dbg com DBG 根
  • freertos系统栈溢出检测机制简述

    FreeRTOS 提供了多种特性来辅助跟踪调试栈相关的问题 uxTaskGetStackHighWaterMark 函数 每个任务都独立维护自己的栈空间 xff0c 栈空间总量在任务创建时进行设定 uxTaskGetStackHighWat
  • 记一次 windows 桌面卡顿

    记一次 windows 桌面卡顿 这几天在 windows 桌面上的操作感觉非常不好 xff0c 一开始以为是电脑老化 网络卡顿 C 盘又被垃圾挤占空间 或什么自启动软件占了内存 xff0c 复制一个快捷键出来都要缓冲 然后就卸载了很多不常
  • 浏览 APT 报告中学习积累

    浏览 APT 报告中学习积累 工具网站积累 xff1a xff08 APT 报告搜寻网站 xff09 https ti qianxin com https feed watcherlab com index apt https malped
  • 《windows 程序设计》读书笔记 一

    目录 基础知识 主要的动态链接库 xff1a API 及内存管理模式 xff1a 第一个 Windows 程序解析 xff1a 头文件 xff1a Windows 程序的入口 xff1a MessageBox 函数 xff1a 基础知识 主