Windows部分常用API

2021/8/5 7:06:31

本文主要是介绍Windows部分常用API,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前言

在此仅记录个人在 Windows 环境中常用的 API, 由于水平有限可能有些 API 记录的不是很详细, 后续会进行补充.

在 Windows 环境下编程请使用微软提供的 Visual Studio 系列编译器

目录

  • CreateProcess()

    • CreateProcessA()

    • CreateProcessW()

  • CreateThread()

  • CreateFile()

    • CreateFileA()

    • CreateFileW()

  • ReadFile()

  • WriteFile()

  • CreateWindow()

    • CreateWindowA()
    • CreateWindowW()

CreateProcess()

顾名思义, 用来创建一个新进程的函数.

CreateProcess() 有两个版本, CreateProcessA(), CreateProcessW(). 在这些 API 中, 带 A 的表示字符串使用 ASCII 编码, 而 W 的则表示字符串使用 Unicode 编码. 除此此外他们的功能基本一致 (指 A 和 W)

关于 Windows 环境下的字符编码可以参考 :
https://www.cnblogs.com/ICeVe/p/15073367.html

返回目录

CreateProcessA()

MSDN文档说明

Creates a new process and its primary thread. The new process runs in the security context of the calling process.

If the calling process is impersonating another user, the new process uses the token for the calling process, not the impersonation token. To run the new process in the security context of the user represented by the impersonation token, use the CreateProcessAsUser or CreateProcessWithLogonW function.

创建一个进程的同时也会建立一个它的线程, 且一般情况下使用的是进程调用的安全令牌. 如果要使用模拟令牌就请使用 CreateProcessAsUser 和 CreateProcessWithLogonW 这两个 API

CreateProcessA() 的结构

BOOL CreateProcessA(
  LPCSTR                lpApplicationName,	
  LPSTR                 lpCommandLine,	
  LPSECURITY_ATTRIBUTES lpProcessAttributes,	
  LPSECURITY_ATTRIBUTES lpThreadAttributes,	
  BOOL                  bInheritHandles,	
  DWORD                 dwCreationFlags,	
  LPVOID                lpEnvironment,	
  LPCSTR                lpCurrentDirectory,	
  LPSTARTUPINFOA        lpStartupInfo,	
  LPPROCESS_INFORMATION lpProcessInformation	
);

部分参数解释

LPCSTR                lpApplicationName

LPCSTR :const char*

MSDN文档说明

The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.

The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a partial name, the function uses the current drive and current directory to complete the specification. The function will not use the search path. This parameter must include the file name extension; no default extension is assumed.

The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space–delimited token in the lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin; otherwise, the file name is ambiguous. For example, consider the string "c:\program files\sub dir\program name". This string can be interpreted in a number of ways. The system tries to interpret the possibilities in the following order:

  1. c:\program.exe
  2. c:\program files\sub.exe
  3. c:\program files\sub dir\program.exe
  4. c:\program files\sub dir\program name.exe

If the executable module is a 16-bit application, lpApplicationName should be NULL, and the string pointed to by lpCommandLine should specify the executable module as well as its arguments.

To run a batch file, you must start the command interpreter; set lpApplicationName to cmd.exe and set lpCommandLine to the following arguments: /c plus the name of the batch file.

该参数用来确定执行进程的模块名及其模块路径 (名称尽量要完整, 如 notepad.exe, cmd.exe 等), 如果该参数是 NULL 则模块名为空格符 . 如果不为 NULL, 则为用引号括起来的模块名及其模块路径 (如果该路径有空格).

还有一点, 如果模块路径不完整, 则会通过多种方式去寻找这个模块, 如写好的程序的根目录下等.


LPSTR                 lpCommandLine

LPSTR :char*

MSDN文档说明

The command line to be executed.

The maximum length of this string is 32,767 characters, including the Unicode terminating null character. If lpApplicationName is NULL, the module name portion of lpCommandLine is limited to MAX_PATH characters.

The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.

The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line.

If both lpApplicationName and lpCommandLine are non-NULL, the null-terminated string pointed to by lpApplicationName specifies the module to execute, and the null-terminated string pointed to by lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C programmers generally repeat the module name as the first token in the command line.

If lpApplicationName is NULL, the first white space–delimited token of the command line specifies the module name. If you are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended. Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period (.) with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory path, the system searches for the executable file in the following sequence:

  1. The directory from which the application loaded.
  2. The current directory for the parent process.
  3. The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.
  4. The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable. Note that this function does not search the per-application path specified by the App Paths registry key. To include this per-application path in the search sequence, use the ShellExecute function.

The system adds a terminating null character to the command-line string to separate the file name from the arguments. This divides the original string into two strings for internal processing.

  1. 命令行参数. 如果该参数为 NULL, 则函数将使用 lpApplicationName 参数指定的字符串当做要运行的程序的命令行参数.
  2. 如果 lpApplicationName 和 lpCommandLine 参数都不为空, 那么 lpApplicationName 参数指定将要被运行的模块, lpCommandLine 参数指定将被运行的模块的命令行, 新运行的进程可以使用 GetCommandLine 函数获得整个命令行.
  3. 如果文件路径包含空格请使用字符串括起来, 例如 "\"C:\\xxx\\xxx\\ xxx\"" 这样, 且尽量写上扩展名.


LPSECURITY_ATTRIBUTES lpProcessAttributes

MSDN文档说明

A pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle to the new process object can be inherited by child processes. If lpProcessAttributes is NULL, the handle cannot be inherited.

The lpSecurityDescriptor member of the structure specifies a security descriptor for the new process. If lpProcessAttributes is NULL or lpSecurityDescriptor is NULL, the process gets a default security descriptor. The ACLs in the default security descriptor for a process come from the primary token of the creator.Windows XP: The ACLs in the default security descriptor for a process come from the primary or impersonation token of the creator. This behavior changed with Windows XP with SP2 and Windows Server 2003.

一个指向 SECURITY_ATTRIBUTES 结构体的指针, 该结构体决定新进程对象的返回句柄是否可以被子进程继承. 如果 lpProcessAttributes 是 NULL , 则这个句柄不能被继承.

一般情况下为 NULL


LPSECURITY_ATTRIBUTES lpThreadAttributes

MSDN文档说明

A pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle to the new thread object can be inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited.

The lpSecurityDescriptor member of the structure specifies a security descriptor for the main thread. If lpThreadAttributes is NULL or lpSecurityDescriptor is NULL, the thread gets a default security descriptor. The ACLs in the default security descriptor for a thread come from the process token.Windows XP: The ACLs in the default security descriptor for a thread come from the primary or impersonation token of the creator. This behavior changed with Windows XP with SP2 and Windows Server 2003.

一个指向 SECURITY_ATTRIBUTES 结构体的指针, 该结构体决定新线程对象的返回句柄是否可以被子线程继承. 如果 lpProcessAttributes 是 NULL , 这个句柄不能被继承.

一般情况下为 NULL


BOOL                  bInheritHandles

MSDN文档说明

If this parameter is TRUE, each inheritable handle in the calling process is inherited by the new process. If the parameter is FALSE, the handles are not inherited. Note that inherited handles have the same value and access rights as the original handles. For additional discussion of inheritable handles, see Remarks.

Terminal Services: You cannot inherit handles across sessions. Additionally, if this parameter is TRUE, you must create the process in the same session as the caller.

Protected Process Light (PPL) processes: The generic handle inheritance is blocked when a PPL process creates a non-PPL process since PROCESS_DUP_HANDLE is not allowed from a non-PPL process to a PPL process. See Process Security and Access Rights

该参数为 TRUE, 则调用进程的每个可继承的句柄被新进程所继承. 如果为 FALSE, 则该句柄不可被继承.

一般情况下为 0


DWORD                 dwCreationFlags

DWROD : 即为 unsigned long

MSDN文档说明

The flags that control the priority class and the creation of the process. For a list of values, see Process Creation Flags.

This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the process's threads. For a list of values, seeGetPriorityClass. If none of the priority class flags is specified, the priority class defaults to NORMAL_PRIORITY_CLASS unless the priority class of the creating process is IDLE_PRIORITY_CLASS or BELOW_NORMAL_PRIORITY_CLASS. In this case, the child process receives the default priority class of the calling process.

If the dwCreationFlags parameter has a value of 0:

  • The process inherits both the error mode of the caller and the parent's console.
  • The environment block for the new process is assumed to contain ANSI characters (see lpEnvironment parameter for additional information).
  • A 16-bit Windows-based application runs in a shared Virtual DOS machine (VDM).

  1. 该参数用来控制创建的进程及其优先级. 具体值可参考 Process Creation Flags
  2. 该参数也可用来控制新进程的优先级, 还决定着进程的线程调度优先级. 具体值可参考 GetPriorityClass
  3. 默认的优先级为 NORMAL_PRIORITY_CLASS

一般情况下为 0


LPVOID                lpEnvironment

LPVOID :void *

MSDN文档说明

A pointer to the environment block for the new process. If this parameter is NULL, the new process uses the environment of the calling process.

An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form:

name=value\0

Because the equal sign is used as a separator, it must not be used in the name of an environment variable.

An environment block can contain either Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains Unicode characters, be sure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT. If this parameter is NULL and the environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT.

The ANSI version of this function, CreateProcessA fails if the total size of the environment block for the process exceeds 32,767 characters.

Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block.

指向一个新进程的环境块. 如果此参数为空, 新进程使用调用进程的环境.

一般设为 NULL


LPCSTR                lpCurrentDirectory

MSDN文档说明

The full path to the current directory for the process. The string can also specify a UNC path.

If this parameter is NULL, the new process will have the same current drive and directory as the calling process. (This feature is provided primarily for shells that need to start an application and specify its initial drive and working directory.)

该进程当前目录的完整路径, 该字符串也能指定 UNC 路径. 如果该参数为 NULL, 新进程将会拥有如同调用进程一样的当前驱动和目录

一般设为 NULL


LPSTARTUPINFOA        lpStartupInfo

LPSTARTUPINFOA : 一个指向 STARTUPINFOA 结构体的指针

MSDN文档说明

A pointer to a STARTUPINFO or STARTUPINFOEX structure.

To set extended attributes, use a STARTUPINFOEX structure and specify EXTENDED_STARTUPINFO_PRESENT in the dwCreationFlags parameter.

Handles in STARTUPINFO or STARTUPINFOEX must be closed with CloseHandle when they are no longer needed.

该参数决定新进程的窗口如何显示, 该参数需要初始化


LPPROCESS_INFORMATION lpProcessInformation

LPPROCESS_INFORMATION : 一个指向 STARTUPINFOA 结构体的指针

MSDN文档说明

A pointer to a PROCESS_INFORMATION structure that receives identification information about the new process.

Handles in PROCESS_INFORMATION must be closed with CloseHandle when they are no longer needed.

该参数决定新进程的信息内容, 该参数需要初始化


该函数的返回类型为 BOOL, 返回值如果为 1, 则调用成功; 反之调用失败

范例

//使用 CreateProcessA() 来创建一个 NotePad.exe 的进程

#include <windows.h>
#include <cstdio>

using namespace std;

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevinstance, LPSTR lpcmdline, int ncmdshow)
{
    STARTUPINFOA StartUp;
    PROCESS_INFORMATION Infor;

    ZeroMemory(&StartUp, sizeof(StartUp));	/*用ZeroMemory这个API对这个结构体进行初始化*/
    StartUp.cb = sizeof(StartUp);
    ZeroMemory(&Infor, sizeof(Infor));

    BOOL IsCreate = CreateProcessA(
        NULL,
        "C:\\Windows\\NotePad.exe",
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &StartUp,
        &Infor);

    if (IsCreate)
        MessageBoxA(NULL, "The process is created successfully.", "Title", MB_OK);
    else
        MessageBoxA(NULL, "The process can't be created normally.", "Title", MB_OK);

    return 0;
}

  • 返回目录

CreateProcessW()

功能与 CreateProcessA() 基本一致, 不过使用的字符串的编码均为 Unicode

CreateProcessW()的结构

BOOL CreateProcessW(
  LPCWSTR               lpApplicationName,
  LPWSTR                lpCommandLine,
  LPSECURITY_ATTRIBUTES lpProcessAttributes,
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  BOOL                  bInheritHandles,
  DWORD                 dwCreationFlags,
  LPVOID                lpEnvironment,
  LPCWSTR               lpCurrentDirectory,
  LPSTARTUPINFOW        lpStartupInfo,
  LPPROCESS_INFORMATION lpProcessInformation
);

注意在使用 wchar_t* 类型的字符串时, 需要将 char* 类型的字符串进行转换.

范例

//使用CreateProcessW()来打开notepad.exe

#include <windows.h>

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevinstance, LPSTR lpcmdline, int ncmdshow)
{
    STARTUPINFOW StartUp;
    PROCESS_INFORMATION Info;

    ZeroMemory(&StartUp, sizeof(StartUp));
    StartUp.cb = sizeof(StartUp);
    ZeroMemory(&Info, sizeof(StartUp));

    WCHAR WPath[50] = L"C:\\Windows\\notepad.exe";

    BOOL IsCreated = CreateProcessW(
        NULL,
        WPath,
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &StartUp,
        &Info);

    if (IsCreated)
        MessageBoxW(NULL, L"The process is created successfully.", L"Title", MB_OK);

    else
        MessageBoxW(NULL, L"The process can't be created.", L"Title", MB_OK);

    return 0;
}

  • 返回目录

CreateThread()

顾名思义, 该 API 用来创建一个新线程

MSDN 文档说明

Creates a thread to execute within the virtual address space of the calling process.

在进程调用的虚拟地址中创建一个线程

CreateThread() 的结构

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES   lpThreadAttributes,
  SIZE_T                  dwStackSize,
  LPTHREAD_START_ROUTINE  lpStartAddress,
  __drv_aliasesMem LPVOID lpParameter,
  DWORD                   dwCreationFlags,
  LPDWORD                 lpThreadId
);

参数解释

LPSECURITY_ATTRIBUTES   lpThreadAttributes

MSDN 文档解释

A pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited.

The lpSecurityDescriptor member of the structure specifies a security descriptor for the new thread. If lpThreadAttributes is NULL, the thread gets a default security descriptor. The ACLs in the default security descriptor for a thread come from the primary token of the creator.

指向一个 SECURITY_ATTRIBUTES 结构体的指针, 以此来决定返回的句柄能否被子进程继承. 如果为 NULL, 则该句柄无法被继承.

一般设置为 NULL

SIZE_T                  dwStackSize

MSDN 文档解释

The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread uses the default size for the executable. For more information, see Thread Stack Size.

设置初始栈的大小, 以字节为单位, 如果为 0, 那么默认将使用与调用该函数的线程相同的栈空间大小.

LPTHREAD_START_ROUTINE  lpStartAddress

MSDN 文档解释

A pointer to the application-defined function to be executed by the thread. This pointer represents the starting address of the thread. For more information on the thread function, see ThreadProc

一个指向线程函数的指针. 关于这个线程函数可参考 ThreadProc

它的一般形式为 :

DWORD WINAPI ThreadProc(
  _In_ LPVOID lpParameter
);

__drv_aliasesMem LPVOID lpParameter

MSDN 文档说明

A pointer to a variable to be passed to the thread.

一个指向向线程传递的参数的指针. 如果不需要这个参数可设为 NULL

DWORD                   dwCreationFlags

MSDN 文档说明

The flags that control the creation of the thread.

Value Meaning
0 The thread runs immediately after creation.
CREATE_SUSPENDED
0x00000004
The thread is created in a suspended state, and does not run until the ResumeThread function is called.
STACK_SIZE_PARAM_IS_A_RESERVATION
0x00010000
The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies the commit size.

线程标志. 参数的意思分别为 :

0 : 线程建立后立刻运行.

CREATE_SUSPENDED0x00000004 : 线程建立后处于挂起状态, 直到 ResumeThread 函数调用它后才会运行

STACK_SIZE_PARAM_IS_A_RESERVATION0x00010000 : 不明

LPDWORD                 lpThreadId

MSDN 文档说明

A pointer to a variable that receives the thread identifier. If this parameter is NULL, the thread identifier is not returned.

保存新线程的 id. 如果为 NULL, 则不会保存新线程的 id.


如果函数调用成功, 则返回新线程的句柄. 否则返回 0

范例

//同时执行 MessageBoxW() 函数

#include <windows.h>

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
    MessageBoxW(NULL, L"Hello, World!", L"Title", MB_OK);

    return 0;
}

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevinstance, LPSTR lpCmdline, int ncmdshow)
{
    HANDLE IsCreated = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);

    if (!IsCreated)
    {
        MessageBoxW(NULL, L"The new thread can't be created!", L"Title", MB_OK);
        return 0;
    }

    else
        MessageBoxW(NULL, L"Hello, World!", L"Title", MB_OK);

    return 0;
}

运行成功会直接弹出两个消息框, 而不是在一个消息框执行完毕后再运行另一个消息框.


在使用多线程时要注意死锁问题, 此外相较于单线程而言多线程占用的内存资源也更多. 因此使用多线程时要多加考虑.

  • 返回目录

CreateFile()

顾名思义, 该 API 用来创建一个新文件.

CreateFile() 有两个版本 : CreateFileA() 和 CreateFileW(). A 和 W 分别代表字符串参数的编码为 ASCII 和 Unicode

  • 返回目录

CreateFileA()

MSDN 文档说明

Creates or opens a file or I/O device. The most commonly used I/O devices are as follows: file, file stream, directory, physical disk, volume, console buffer, tape drive, communications resource, mailslot, and pipe. The function returns a handle that can be used to access the file or device for various types of I/O depending on the file or device and the flags and attributes specified.

To perform this operation as a transacted operation, which results in a handle that can be used for transacted I/O, use the CreateFileTransacted function.

创建或打开一个文件或 IO 设备.

CreateFileA() 的结构

HANDLE CreateFileA(
  LPCSTR                lpFileName,
  DWORD                 dwDesiredAccess,
  DWORD                 dwShareMode,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD                 dwCreationDisposition,
  DWORD                 dwFlagsAndAttributes,
  HANDLE                hTemplateFile
);

参数解释

LPCSTR                lpFileName

MSDN 文档说明

The name of the file or device to be created or opened. You may use either forward slashes (/) or backslashes () in this name.

In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\?" to the path. For more information, see Naming Files, Paths, and Namespaces.

For information on special device names, see Defining an MS-DOS Device Name.

To create a file stream, specify the name of the file, a colon, and then the name of the stream. For more information, see File Streams.

设置文件或设备的名字. 在 ASCII 编码下的名字的长度限定在 MAX_PATH (即 260) 个字符, 在 Unicode 编码下的名字长度限定在 32767 个字符.

DWORD                 dwDesiredAccess

MSDN 文档说明

The requested access to the file or device, which can be summarized as read, write, both or neither zero).

The most commonly used values are GENERIC_READ, GENERIC_WRITE, or both (GENERIC_READ | GENERIC_WRITE). For more information, see Generic Access Rights, File Security and Access Rights, File Access Rights Constants, and ACCESS_MASK.

If this parameter is zero, the application can query certain metadata such as file, directory, or device attributes without accessing that file or device, even if GENERIC_READ access would have been denied.

You cannot request an access mode that conflicts with the sharing mode that is specified by the dwShareMode parameter in an open request that already has an open handle.

For more information, see the Remarks section of this topic and Creating and Opening Files.

文件的访问类型, 是只读, 只写还是两者皆有. 该参数常见的为 GENERIC_READ, GENERIC_WRITE 或者是 (GENERIC_READ | GENERIC_WRITE).

DWORD                 dwShareMode

MSDN 文档说明

The requested sharing mode of the file or device, which can be read, write, both, delete, all of these, or none (refer to the following table). Access requests to attributes or extended attributes are not affected by this flag.

If this parameter is zero and CreateFile succeeds, the file or device cannot be shared and cannot be opened again until the handle to the file or device is closed. For more information, see the Remarks section.

You cannot request a sharing mode that conflicts with the access mode that is specified in an existing request that has an open handle. CreateFile would fail and the GetLastError function would return ERROR_SHARING_VIOLATION.

To enable a process to share a file or device while another process has the file or device open, use a compatible combination of one or more of the following values. For more information about valid combinations of this parameter with the dwDesiredAccess parameter, see Creating and Opening Files.

Value Meaning
0
0x00000000
Prevents other processes from opening a file or device if they request delete, read, or write access.
FILE_SHARE_DELETE
0x00000004
Enables subsequent open operations on a file or device to request delete access.Otherwise, other processes cannot open the file or device if they request delete access.If this flag is not specified, but the file or device has been opened for delete access, the function fails.Note Delete access allows both delete and rename operations.
FILE_SHARE_READ
0x00000001
Enables subsequent open operations on a file or device to request read access.Otherwise, other processes cannot open the file or device if they request read access.If this flag is not specified, but the file or device has been opened for read access, the function fails.
FILE_SHARE_WRITE
0x00000002
Enables subsequent open operations on a file or device to request write access.Otherwise, other processes cannot open the file or device if they request write access.If this flag is not specified, but the file or device has been opened for write access or has a file mapping with write access, the function fails.

文件或设备的共享类型.

如果为 0, 表示不共享; 如果是 FILE_SHARE_DELETE, 则表示共享的文件能执行删除操作; 如果是 FILE_SHARE_READ, 则表示共享的文件能执行读操作; 如果是 FILE_SHAREWRITE. 则表示共享的文件能执行写操作. 如果这三种类型都想使用的话可将它们按位或即可. (FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHAREWRITE)

LPSECURITY_ATTRIBUTES lpSecurityAttributes

MSDN 文档说明

A pointer to a SECURITY_ATTRIBUTES structure that contains two separate but related data members: an optional security descriptor, and a Boolean value that determines whether the returned handle can be inherited by child processes.

This parameter can be NULL.

If this parameter is NULL, the handle returned by CreateFile cannot be inherited by any child processes the application may create and the file or device associated with the returned handle gets a default security descriptor.

The lpSecurityDescriptor member of the structure specifies a SECURITY_DESCRIPTOR for a file or device. If this member is NULL, the file or device associated with the returned handle is assigned a default security descriptor.

CreateFile ignores the lpSecurityDescriptor member when opening an existing file or device, but continues to use the bInheritHandle member.

The bInheritHandle member of the structure specifies whether the returned handle can be inherited.

For more information, see the Remarks section.

一个指向 SECURITY_ATTRIBUTES 结构体的指针, 该参数决定文件的安全特性.

一般设为 NULL

 DWORD                 dwCreationDisposition

MSDN 文档说明

An action to take on a file or device that exists or does not exist.

For devices other than files, this parameter is usually set to OPEN_EXISTING.

For more information, see the Remarks section.

This parameter must be one of the following values, which cannot be combined:

Value Meaning
CREATE_ALWAYS
2
Creates a new file, always.If the specified file exists and is writable, the function overwrites the file, the function succeeds, and last-error code is set to ERROR_ALREADY_EXISTS (183).If the specified file does not exist and is a valid path, a new file is created, the function succeeds, and the last-error code is set to zero.For more information, see the Remarks section of this topic.
CREATE_NEW
1
Creates a new file, only if it does not already exist.If the specified file exists, the function fails and the last-error code is set to ERROR_FILE_EXISTS (80).If the specified file does not exist and is a valid path to a writable location, a new file is created.
OPEN_ALWAYS
4
Opens a file, always.If the specified file exists, the function succeeds and the last-error code is set to ERROR_ALREADY_EXISTS (183).If the specified file does not exist and is a valid path to a writable location, the function creates a file and the last-error code is set to zero.
OPEN_EXISTING
3
Opens a file or device, only if it exists.If the specified file or device does not exist, the function fails and the last-error code is set to ERROR_FILE_NOT_FOUND (2).For more information about devices, see the Remarks section.
TRUNCATE_EXISTING
5
Opens a file and truncates it so that its size is zero bytes, only if it exists.If the specified file does not exist, the function fails and the last-error code is set to ERROR_FILE_NOT_FOUND (2).The calling process must open the file with the GENERIC_WRITE bit set as part of the dwDesiredAccess parameter.

对一个存在或不存在的文件或设备进行操作.

CREATE_ALWAYS : 创建一个新文件, 如果文件存在则错误代码 ERROR_ALREADY_EXISTS(183) 会被设置, 同时会其进行覆写. 如果文件不存在则错误代码会设置成 0, 且函数调用成功.

CREATE_NEW : 创建一个新文件, 如果文件存在则错误代码 ERROR_FILE_EXISTS(80) 会被设置, 同时函数调用失败.

OPEN_ALWAYS : 打开一个文件, 如果文件存在则错误代码 ERROR_ALREADY_EXISTS(183) 会被设置, 函数调用成功. 如果文件不存在则错误代码会设置成 0, 且会创建一个新文件.

OPEN_EXISTING : 打开一个已经存在的文件. 如果该文件不存在则错误代码 ERROR_FILE_NOT_FOUND 会被设置, 函数调用失败.

TRUNCATE_EXISTING : 打开一个已经存在的文件并将其内容缩短至 0 字节. 如果文件不存在则错误代码 ERROR_FILE_NOT_FOUND(2) 会被设置, 且函数调用失败.

DWORD                 dwFlagsAndAttributes

MSDN 文档说明

The file or device attributes and flags, FILE_ATTRIBUTE_NORMAL being the most common default value for files.

This parameter can include any combination of the available file attributes (FILE_ATTRIBUTE_*). All other file attributes override FILE_ATTRIBUTE_NORMAL.

This parameter can also contain combinations of flags (FILE_FLAG_) for control of file or device caching behavior, access modes, and other special-purpose flags. These combine with any FILE_ATTRIBUTE_ values.

This parameter can also contain Security Quality of Service (SQOS) information by specifying the SECURITY_SQOS_PRESENT flag. Additional SQOS-related flags information is presented in the table following the attributes and flags tables.

设置文件或设备的属性.

常用的有 :

FILE_ATTRIBUTE_NORMAL 默认属性

FILE_ATTRIBUTE_HIDDEN 隐藏文件或目录

FILE_ATTRIBUTE_READONLY 文件为只读

HANDLE                hTemplateFile

MSDN 文档说明

A valid handle to a template file with the GENERIC_READ access right. The template file supplies file attributes and extended attributes for the file that is being created.

This parameter can be NULL.

When opening an existing file, CreateFile ignores this parameter.

When opening a new encrypted file, the file inherits the discretionary access control list from its parent directory. For additional information, see File Encryption.

一个有 GENERIC_READ 访问权限的模板文件的有效句柄.

一般设置为 NULL


如果函数调用成功, 返回一个该文件的有效句柄; 否则返回错误代码 INVALID_HANDLE_VALUE

范例

//创建一个 C++.txt 文件

#include <windows.h>

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevinstance, LPSTR lpCmdline, int ncmdshow)
{
    HANDLE IsCreated = CreateFileA(
        "D:\\C++.txt",
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        CREATE_NEW,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    CHAR Path[] = "notepad.exe D:\\C++.txt";
    STARTUPINFOA StartUp;
    PROCESS_INFORMATION Info;

    ZeroMemory(&StartUp, sizeof(StartUp));
    StartUp.cb = sizeof(StartUp);
    ZeroMemory(&Info, sizeof(Info));

    if (!IsCreated)
        MessageBoxW(NULL, L"The file can't be created!", L"Title", MB_OK);

    else
    {
        MessageBoxW(NULL, L"The file is created successfully!", L"Title", MB_OK);
        CreateProcessA(NULL, Path, NULL, NULL, FALSE, 0, NULL, NULL, &StartUp, &Info);
    }

    return 0;
}

  • 返回目录

CreateFileW()

CreateFileW() 和 CreateFileA() 没有什么太大的区别, 主要是参数中的字符串编码都为 Unicode

CreateFileW() 的结构

HANDLE CreateFileW(
  LPCWSTR               lpFileName,
  DWORD                 dwDesiredAccess,
  DWORD                 dwShareMode,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD                 dwCreationDisposition,
  DWORD                 dwFlagsAndAttributes,
  HANDLE                hTemplateFile
);

  • 返回目录

ReadFile()

顾名思义, 对文件进行读操作

MSDN 文档说明

Reads data from the specified file or input/output (I/O) device. Reads occur at the position specified by the file pointer if supported by the device.

This function is designed for both synchronous and asynchronous operations. For a similar function designed solely for asynchronous operation, see ReadFileEx.

从文件或 IO 设备中读数据. 该函数使用同步机制

ReadFile() 的结构

BOOL ReadFile(
  HANDLE       hFile,
  LPVOID       lpBuffer,
  DWORD        nNumberOfBytesToRead,
  LPDWORD      lpNumberOfBytesRead,
  LPOVERLAPPED lpOverlapped
);

参数解释

HANDLE       hFile

MSDN 文档说明

A handle to the device (for example, a file, file stream, physical disk, volume, console buffer, tape drive, socket, communications resource, mailslot, or pipe).

The hFile parameter must have been created with read access. For more information, see Generic Access Rights and File Security and Access Rights.

For asynchronous read operations, hFile can be any handle that is opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile function, or a socket handle returned by the socket or accept function.

一个文件或设备的的句柄, 且其访问类型需要为只读类型

LPVOID       lpBuffer

MSDN 文档说明

A pointer to the buffer that receives the data read from a file or device.

This buffer must remain valid for the duration of the read operation. The caller must not use this buffer until the read operation is completed.

一个指向存储由文件或设备所读的数据的容器指针. 该容器必须在读期间保持有效

DWORD        nNumberOfBytesToRead

MSDN 文档说明

The maximum number of bytes to be read.

所读的最大字节数

LPDWORD      lpNumberOfBytesRead

MSDN 文档说明

A pointer to the variable that receives the number of bytes read when using a synchronous hFile parameter. ReadFile sets this value to zero before doing any work or error checking. Use NULL for this parameter if this is an asynchronous operation to avoid potentially erroneous results.

This parameter can be NULL only when the lpOverlapped parameter is not NULL.

For more information, see the Remarks section.

一个指向接受所读文件的字节大小的变量指针. 该参数可设为 NULL, 只有当下一个参数 lpOverlapped 不是 NULL 或避免潜在的错误结果的异步操作时设置.

LPOVERLAPPED lpOverlapped

MSDN 文档说明

A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL.

If hFile is opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must point to a valid and unique OVERLAPPED structure, otherwise the function can incorrectly report that the read operation is complete.

For an hFile that supports byte offsets, if you use this parameter you must specify a byte offset at which to start reading from the file or device. This offset is specified by setting the Offset and OffsetHigh members of the OVERLAPPED structure. For an hFile that does not support byte offsets, Offset and OffsetHigh are ignored.

For more information about different combinations of lpOverlapped and FILE_FLAG_OVERLAPPED, see the Remarks section and the Synchronization and File Position section.

如果 hFile 参数是用 FILE_FLAG_OVERLAPPED 打开的, 则需要一个指向 OVERLAPPED 结构的指针, 否则为 NULL.


如果函数调用成功返回非 0, 否则返回 0

范例

注意这里需要使用在 CreateFileA() 中创建的 C++.txt 文件, 并且要在里面写上一些字.

//读 C++.txt 中的数据

#include <windows.h>

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevinstance, LPSTR lpCmdline, int ncmdshow)
{
    CHAR Buffer[256]; // 用来存储 C++.txt 中的数据
    DWORD sz;
    HANDLE File;        // CreateFIleA 返回的句柄
    WCHAR WBuffer[256]; // 如果是里面有汉字则需要进行转换所使用的容器

    File = CreateFileA(
        "D:\\C++.txt",
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (!File)
    {
        MessageBoxW(NULL, L"The file isn't existed!", L"Title", MB_OK);
        
        return 0;
    }

    BOOL IsRead = ReadFile(File, Buffer, 256, &sz, NULL);

    if (IsRead)
    {
        MessageBoxW(NULL, L"The file is read successfully!", L"Title", MB_OK);

        BOOL IsTransformed = MultiByteToWideChar(CP_UTF8, NULL, Buffer, -1, WBuffer, 256);

        if (IsTransformed)
        {
            MessageBoxW(NULL, L"The file conversion succeeded!", L"Title", MB_OK);
            MessageBoxW(NULL, WBuffer, L"Title", MB_OK);
        }
        
        else
            return 0;
    }

    return 0;
}

C++.txt 中我写的是 你好, 世界, 经过转换后输出正常

  • 返回目录

WriteFile()

顾名思义, 对文件进行写操作

MSDN 文档说明

Writes data to the specified file or input/output (I/O) device.

This function is designed for both synchronous and asynchronous operation. For a similar function designed solely for asynchronous operation, see WriteFileEx.

向指定的文件或设备进行数据写入操作, 且该函数使用同步机制. 同时该函数的结构与 ReadFile() 基本一致.

WriteFile() 的结构

BOOL WriteFile(
  HANDLE       hFile,
  LPCVOID      lpBuffer,
  DWORD        nNumberOfBytesToWrite,
  LPDWORD      lpNumberOfBytesWritten,
  LPOVERLAPPED lpOverlapped
);

参数解释

DWORD        nNumberOfBytesToWrite

MSDN 文档说明

The number of bytes to be written to the file or device.

A value of zero specifies a null write operation. The behavior of a null write operation depends on the underlying file system or communications technology.

Windows Server 2003 and Windows XP: Pipe write operations across a network are limited in size per write. The amount varies per platform. For x86 platforms it's 63.97 MB. For x64 platforms it's 31.97 MB. For Itanium it's 63.95 MB. For more information regarding pipes, see the Remarks section.

要向文件或设备中写入数据的字节数. 如果为 0 则表示不写入. 不写入操作取决于文件系统和通信技术.

LPDWORD      lpNumberOfBytesWritten

MSDN 文档说明

A pointer to the variable that receives the number of bytes written when using a synchronous hFile parameter. WriteFile sets this value to zero before doing any work or error checking. Use NULL for this parameter if this is an asynchronous operation to avoid potentially erroneous results.

This parameter can be NULL only when the lpOverlapped parameter is not NULL.

For more information, see the Remarks section.

一个指向接受写入的字节个数的变量指针. 该参数可设为 NULL, 只有当下一个参数 lpOverlapped 不是 NULL 或避免潜在的错误结果的异步操作时设置.


函数调用成功时返回非 0 值, 否则返回 0

范例

//创建一个 C++.txt 文件, 并在文件中写入一些字

#include <windows.h>

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevinstance, LPSTR lpcmdline, int ncmdshow)
{
    WCHAR Text[] = L"你好, 世界! Hello, World!";
    WCHAR Path[] = L"notepad.exe D:\\C++.txt";
    DWORD sz;

    HANDLE IsCreated = CreateFileA(
        "D:\\C++.txt",
        GENERIC_WRITE | GENERIC_READ,
        0,
        NULL,
        CREATE_NEW,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (IsCreated)
    {
        BOOL IsWrited = WriteFile(IsCreated, Text, sizeof(Text), &sz, NULL);

        if (IsWrited)
        {
            STARTUPINFOW StartUp;
            PROCESS_INFORMATION Info;

            ZeroMemory(&StartUp, sizeof(StartUp));
            StartUp.cb = sizeof(StartUp);
            ZeroMemory(&Info, sizeof(Info));

            CreateProcessW(
                NULL,
                Path,
                NULL,
                NULL,
                FALSE,
                0,
                NULL,
                NULL,
                &StartUp,
                &Info);
        }

        else
            return 0;
    }

    return 0;
}

如果成功的, C++.txt 中会出现 你好, 世界! Hello, World! 但是如果仔细观察会发现, 这些字符用的是 UTF-16 编码. 如果要换成别的编码方式可使用 WideCharToMultiByte() 进行转换.

范例

//创建一个 C++.txt 文件, 并在文件中写入一些字

#include <windows.h>

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevinstance, LPSTR lpcmdline, int ncmdshow)
{
    WCHAR Text[] = L"你好, 世界! Hello, World!";
    WCHAR Path[] = L"notepad.exe D:\\C++.txt";
    LPSTR CText = NULL;	//存储转换后的字符串
    DWORD szBuffer;	//转换后的字符串长度
    DWORD sz;

    HANDLE IsCreated = CreateFileA(
        "D:\\C++.txt",
        GENERIC_WRITE | GENERIC_READ,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    szBuffer = WideCharToMultiByte(CP_UTF8, NULL, Text, -1, CText, 0, NULL, NULL);
    /*这里先得到转换后的字符串长度*/
    
    CText = (LPSTR)malloc(szBuffer * sizeof(CHAR));
    WideCharToMultiByte(CP_UTF8, NULL, Text, -1, CText, szBuffer, NULL, NULL);

    if (IsCreated)
    {
        BOOL IsWrited = WriteFile(IsCreated, CText, szBuffer, &sz, NULL);

        if (IsWrited)
        {
            STARTUPINFOW StartUp;
            PROCESS_INFORMATION Info;

            ZeroMemory(&StartUp, sizeof(StartUp));
            StartUp.cb = sizeof(StartUp);
            ZeroMemory(&Info, sizeof(Info));

            CreateProcessW(
                NULL,
                Path,
                NULL,
                NULL,
                FALSE,
                0,
                NULL,
                NULL,
                &StartUp,
                &Info);
        }

        else
            return 0;
    }

    return 0;
}

这样就可以将 UTF-16 转换为 UTF-8 了

  • 返回目录

CreateWindow()

顾名思义, 创建一个窗口. 它有两个版本, 一个为 CreateWindowA() 和 CreateWindowW(). 该函数与上述那些函数在使用方面有很大的不同. 新增加了窗口类等概念

  • 返回目录

CreateWindowA()

MSDN 文档说明

Creates an overlapped, pop-up, or child window. It specifies the window class, window title, window style, and (optionally) the initial position and size of the window. The function also specifies the window's parent or owner, if any, and the window's menu.

To use extended window styles in addition to the styles supported by CreateWindow, use the CreateWindowEx function.

创建一个折叠, 弹出或子窗口. 它确定了窗口类, 窗口标题, 窗口风格和窗口的初始位置及大小等

CreateWindowA() 的结构

HANDLE CreateWindowA(
   LPCTSTR lpClassName,
   LPCTSTR lpWindowName,
   DWORD dwStyle,
   int x,
   int y,
   int nWidth,
   int nHeight,
   HWND hWndParent,
   HMENU hMenu,
   hInstance hInstance,
   LPVOID lpParam
);

参数解释

LPCTSTR lpClassName

MSDN 文档说明

A null-terminated string or a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpClassName; the high-order word must be zero. If lpClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, provided that the module that registers the class is also the module that creates the window. The class name can also be any of the predefined system class names. For a list of system class names, see the Remarks section.

一个通过调用 RegisterClass 或 RegisterClassEx (关于这个函数和 RegisterClass 的区别可自行了解, 这里只用 RegisterClass) 创造的一个带 '\0' 的字符串或原子类.

如果是一个字符串, 则该字符串作为这个窗口类的名字.

LPCTSTR lpWindowName

MSDN 文档说明

The window name. If the window style specifies a title bar, the window title pointed to by lpWindowName is displayed in the title bar. When using CreateWindow to create controls, such as buttons, check boxes, and static controls, use lpWindowName to specify the text of the control. When creating a static control with the SS_ICON style, use lpWindowName to specify the icon name or identifier. To specify an identifier, use the syntax "#num".

窗口的标题. 如果窗口风格有特定的标题栏, 那么 lpWindowName 字符串参数则作为标题栏的名字.

DWORD dwStyle

MSDN 文档说明

The style of the window being created. This parameter can be a combination of the window style values, plus the control styles indicated in the Remarks section.

窗口的风格. 可在 window style values 自行了解.

int x

MSDN 文档说明

The initial horizontal position of the window. For an overlapped or pop-up window, the x parameter is the initial x-coordinate of the window's upper-left corner, in screen coordinates. For a child window, x is the x-coordinate of the upper-left corner of the window relative to the upper-left corner of the parent window's client area. If this parameter is set to CW_USEDEFAULT, the system selects the default position for the window's upper-left corner and ignores the y parameter. CW_USEDEFAULT is valid only for overlapped windows; if it is specified for a pop-up or child window, the x and y parameters are set to zero.

窗口的初始水平位置. 对一个层叠或弹出式窗口, x 参数是屏幕坐标系的窗口的左上角的初始 x 坐标. 对于子窗口, x 是子窗口左上角相对父窗口客户区左上角的初始 x 坐标. 如果该参数被设为 CW_USEDEFAULT 则系统为窗口选择缺省的左上角坐标并忽略 y 参数. 如果是一个弹出式窗口或子窗口, 则 x 和 y 都应该设为 0

int y

MSDN 文档说明

The initial vertical position of the window. For an overlapped or pop-up window, the y parameter is the initial y-coordinate of the window's upper-left corner, in screen coordinates. For a child window, y is the initial y-coordinate of the upper-left corner of the child window relative to the upper-left corner of the parent window's client area. For a list box, y is the initial y-coordinate of the upper-left corner of the list box's client area relative to the upper-left corner of the parent window's client area.

If an overlapped window is created with the WS_VISIBLE style bit set and the x parameter is set to CW_USEDEFAULT, then the y parameter determines how the window is shown. If the y parameter is CW_USEDEFAULT, then the window manager calls ShowWindow with the SW_SHOW flag after the window has been created. If the y parameter is some other value, then the window manager calls ShowWindow with that value as the nCmdShow parameter.

窗口的初始垂直位置. 对一个层叠或弹出式窗口, y 参数是屏幕坐标系的窗口的左上角的初始 y 坐标. 对于子窗口, y 是子窗口左上角相对父窗口客户区左上角的初始 y 坐标. 对于列表框, y 是列表框客户区左上角相对父窗口客户区左上角的初始 y 坐标.

如果层叠式窗口风格参数被设置为 WS_VISIBLE, 则 x 参数被设置为 CW_USEDEFAULT, 那么 y 参数决定窗口如何展示. 如果 y 参数被设置为 CW_USEDEFAULT, 那么窗口在被创建后会调用使用 SW_SHOW 标志的 ShowWindow 函数.

如果 y 参数是一些其他的值, 那么窗口管理将会调用使用 nCmdShow 参数的 ShowWindow 函数.

int nWidth

MSDN 文档说明

The width, in device units, of the window. For overlapped windows, nWidth is either the window's width, in screen coordinates, or CW_USEDEFAULT. If nWidth is CW_USEDEFAULT, the system selects a default width and height for the window; the default width extends from the initial x-coordinate to the right edge of the screen, and the default height extends from the initial y-coordinate to the top of the icon area. CW_USEDEFAULT is valid only for overlapped windows; if CW_USEDEFAULT is specified for a pop-up or child window, nWidth and nHeight are set to zero.

窗口的宽度. 对于层叠式窗口, 该参数可以是窗口的宽度, 屏幕坐标或者是 CW_USEDEFAULT.

**如果是 **CW_USEDEFAULT , 则窗口宽度为默认宽度.

对于弹出式窗口或子窗口, 该参数应该设为 0.

int nHeight

MSDN 文档说明

The height, in device units, of the window. For overlapped windows, nHeight is the window's height, in screen coordinates. If nWidth is set to CW_USEDEFAULT, the system ignores nHeight.

窗口的高度. 对于层叠式窗口, 该参数即是窗口的高度, 也是屏幕的坐标. 如果 nWidth 被设置为 CW_USEDEFAULT, 则系统忽略高度参数

HWND hWndParent

MSDN 文档说明

A handle to the parent or owner window of the window being created. To create a child window or an owned window, supply a valid window handle. This parameter is optional for pop-up windows.

To create a message-only window, supply HWND_MESSAGE or a handle to an existing message-only window.

父窗口或主窗口创建的句柄.

一般设为 NULL

HMENU hMenu

MSDN 文档说明

A handle to a menu, or specifies a child-window identifier depending on the window style. For an overlapped or pop-up window, hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used. For a child window, hMenu specifies the child-window identifier, an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window.

一个 MENU 句柄, 或者是取决于子窗口风格的标识符. 对于层叠或弹出式窗口, 该参数指定窗口使用的菜单. 如果餐单类被使用则该参数设为 NULL. 对于子窗口, 该参数作为子窗口的标识符.

hInstance hInstance

MSDN 文档说明

A handle to the instance of the module to be associated with the window.

与窗口相关联的模块句柄

LPVOID lpParam

MSDN 文档说明

A pointer to a value to be passed to the window through the CREATESTRUCT structure (lpCreateParams member) pointed to by the lParam param of the WM_CREATE message. This message is sent to the created window by this function before it returns.

If an application calls CreateWindow to create a MDI client window, lpParam should point to a CLIENTCREATESTRUCT structure. If an MDI client window calls CreateWindow to create an MDI child window, lpParam should point to a MDICREATESTRUCT structure. lpParam may be NULL if no additional data is needed.

一个指向一个值的指针,该指针通过 CREATESTRUCT 结构体传递 WM_CREATE 窗口信息.

一般设为 NULL


函数调用成功返回一个 HWND 句柄, 否则返回 0

在创建窗口前, 需要注册一个窗口类, 窗口类确定了处理信息窗口的窗口过程. 窗口类分为 WNDCLASSA, WNDCLASSW, WNDCLASSEXA, WNDCLASSEXW. 一般常用的是 WNDCLASSA, WNDCLASSW. 关于它们内部变量的作用可自行了解

WNDCLASSA, WNDCLASSW 的结构如下

typedef struct tagWNDCLASSA {
  UINT      style;
  WNDPROC   lpfnWndProc;
  int       cbClsExtra;
  int       cbWndExtra;
  HINSTANCE hInstance;
  HICON     hIcon;
  HCURSOR   hCursor;
  HBRUSH    hbrBackground;
  LPCSTR    lpszMenuName;
  LPCSTR    lpszClassName;
} WNDCLASSA, *PWNDCLASSA, *NPWNDCLASSA, *LPWNDCLASSA;

typedef struct tagWNDCLASSW {
  UINT      style;
  WNDPROC   lpfnWndProc;
  int       cbClsExtra;
  int       cbWndExtra;
  HINSTANCE hInstance;
  HICON     hIcon;
  HCURSOR   hCursor;
  HBRUSH    hbrBackground;
  LPCWSTR   lpszMenuName;
  LPCWSTR   lpszClassName;
} WNDCLASSW, *PWNDCLASSW, *NPWNDCLASSW, *LPWNDCLASSW;

范例

//创建一个 Windows 窗口

#include <windows.h>

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;

    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        GetClientRect(hwnd, &rect);

        DrawTextW(hdc, L"Hello, Windows 10", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevinstance, LPSTR lpcmdline, int ncmdshow)
{
    WCHAR szAppName[] = L"Windows";
    WCHAR szClassTitle[] = L"Hello, World!";
    HWND hwnd;
    WNDCLASSW wndclass;
    MSG msg;

    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hinstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClassW(&wndclass))
        return 0;

    hwnd = CreateWindowW(
        szAppName,
        szClassTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hinstance,
        NULL);

    ShowWindow(hwnd, ncmdshow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

  • 回到目录

CreateWindowW()

作用与 CreateWindowA() 基本一样, 唯一的区别在于参数中的字符串的字符编码为 Unicode

CreateWindowW() 的结构

HANDLE CreateWindowW(
   LPCTSTR lpClassName,
   LPCTSTR lpWindowName,
   DWORD dwStyle,
   int x,
   int y,
   int nWidth,
   int nHeight,
   HWND hWndParent,
   HMENU hMenu,
   hInstance hInstance,
   LPVOID lpParam
);


范例

见 CreateWindowA() 的范例

  • 返回目录


这篇关于Windows部分常用API的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程