认识控制台-控制台句柄、附着到控制台、关闭控制台

导读:
  附着到一个控制台
  一个进程可以使用AttachConsole函数来附着到一个控制台上,一个进程只能附着一个控制台。
  一个控制台可以有许多进程附着到它上面,调用GetConsoleProcessList函数可以得到附着到一个控制台的列表。
  
  关闭一个控制台
  进程可以使用FreeConsole函数来将其自身从一个控制台脱离出来。如果其他进程共享这个控制台,控制台不会被销毁,但调用FreeConsole函数的进程不能在使用它了,在进程调用FreeConsole之后,它可以使用AllocConsole来创建一个新的控制台或AttachConsole来附着到另一个控制台上。
  控制在最后一个附着的进程关闭的时候或调用FreeConsole的时候被关闭。
  
  控制台句柄
  
  控制台进程使用句柄来访问控制台的输入和屏幕缓冲区。一个进程可以使用GetStdHandle、CreateFile或CreateConsoleScreenBuffer函数来打开这些句柄。
  GetStdHandle函数提供一个获得进程相关的标准输入(STDIN)、标准输出(STDOUT)和标准错误(STDERR)句柄。在控制台创建过程中,系统创建这些句柄。最初的STDIN是一个指向控制台输入缓冲区的句柄,STDOUT和STDERR是控制台活动屏幕缓冲区的句柄。然而,SetStdHandle函数可以改变STDIN、STDOUT、STDERR关联的句柄来重定向标准句柄。因为父进程的标准句柄可以被子进程继承,后面调用GetStdHandle函数返回的是重定向的句柄。GetStdHandle返回的句柄可以指向其他的句柄不一定是控制台I/O。例如,在创建子进程之前,父亲进程使用SetStdHandle来将STDIN设置为一个管道句柄,那么这个特性会被子进程继承。当子进程调用GetStdHandle的时候返回的是管道句柄。这意味着父亲进程能控制子进程的标准句柄,GetStdHandle返回的句柄有GENERIC_READ|GENERIC_WRITE访问权限,当然如果在SetStdHandle的时候设置较少的访问权限另外说。
  GetStdHandle返回的句柄值不是0,1,2,因此在Stdio.h(STDIN,STDOUT和STDERR)中预定义的流常量不能在需要一个控制台句柄的函数中使用。
  CreateFile函数即使STDIN和STDOUT没有被重定向的情况下,也可以让一个进程得到输入缓冲区和活动屏幕缓冲区的句柄。为了打开一个控制台输入缓冲区的句柄,需要在调用CreateFile的时候指定CONIN$值,而指定CONOUT$值可以打开一个控制台活动屏幕缓冲区的句柄。CreateFile函数使你可以通过它返回的句柄来读写操作。
  函数CreateConsoleScreenBuffer创建一个新的屏幕缓冲区且返回这个句柄,这个句柄可以在所有接受一个控制输出作为参数的函数中使用。新的屏幕缓冲区不会是活动的,只有调用SetConsoleActiveScreenBuffer函数的时候指定该值才会被设置为活动的。活动屏幕缓冲区的改变不会改变GetStdHandle的值,同样使用SetStdHandle改变STDOUT句柄也不会影响活动屏幕缓冲区。
  CreateFile和CreateConsoleScreenBuffer函数返回的句柄能在任何需要控制台输入缓冲区或控制台屏幕缓冲区作为参数的函数中,GetStdHandle返回的句柄只要没有被重定向为其他的句柄都可以在控制台函数中使用,如果标准句柄被重定向为指向一个文件或管道,这些句柄只能被ReadFile和WriteFile函数使用。
  进程可以使用DuplicateHandle函数来创建一个控制台句柄的副本,可以指定不同的访问和继承权限。注意,进程可以自己使用而创建一个控制台句柄副本。这与其他的句柄类型不同(例如文件、管道、信号量对象),这些类型可以通过DuplicateHandle来创建一个有效的句柄,而别的进程也可以使用。

本文转自
http://blog.csdn.net/yangjiudan/archive/2006/04/29/697517.aspx
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
1. 去掉不必要的头文件 这段代码中包含了很多不必要的头文件,可以考虑删除。 2. 统一头文件的引用方式 头文件的引用方式不统一,有的使用<>,有的使用"",可以考虑统一使用<>或""。 3. 去掉重复的头文件 这段代码中出现了重复的头文件,比如<stdio.h>、<windows.h>等,可以考虑删除。 4. 函数参数使用const 在函数定义时,如果某个参数不会被修改,可以将其声明为const类型,以增加代码的可读性和安全性。 5. 函数名使用动词开头 函数名应该使用动词开头,表明该函数的功能。 6. 优化循环结构 在循环结构中,可以将重复的代码提取出来,减少代码量。 7. 使用宏定义 在代码中出现了一些魔法数,可以考虑使用宏定义来提高代码的可读性。 8. 使用函数封装 可以将一些功能相似的代码封装成函数,提高代码的可读性和复用性。 9. 增加注释 在代码中增加注释,能够更好地帮助理解代码的功能和逻辑。 基于以上改进方向,可以对该代码进行如下改进: ```c #include "graphics.h" #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <math.h> #define PI 3.1415926 #define HEX_ANGLE 60.0 // 六边形的角度 #define TURN_ANGLE 20.0 // 每次转动的角度 void drawHexagon(double cx, double cy, double size); // 绘制六边形 void forward(double distance, double angle); // 沿着当前方向画出一定长度的线段 void turn(double angle); // 画笔方向转动一定的角度 void Main() { InitGraphics(); // 创建画布 SetPenColor("green"); SetPenSize(2); double cx = GetWindowWidth() / 2.0; double cy = GetWindowHeight() / 2.0; for (int i = 0; i < 18; i++) { drawHexagon(cx, cy, 1.0); turn(TURN_ANGLE); } WaitMouseClick(); CloseGraphics(); } void drawHexagon(double cx, double cy, double size) { MovePen(cx + size, cy); for (int i = 0; i < 6; i++) { forward(2 * size, HEX_ANGLE); } } void forward(double distance, double angle) { double dx = distance * cos(angle * PI / 180); double dy = distance * sin(angle * PI / 180); DrawLine(dx, dy); } void turn(double angle) { newangle += angle; } ``` 这份代码的改进包含以下方面: 1. 去掉不必要的头文件 这份代码中只保留了graphics.h和stdio.h两个头文件,其他头文件都被删除了。 2. 统一头文件的引用方式 这份代码中统一使用<>来引用头文件。 3. 去掉重复的头文件 这份代码中只保留了stdio.h一个头文件。 4. 函数参数使用const 这份代码中没有需要使用const的参数。 5. 函数名使用动词开头 函数名都使用了动词开头。 6. 优化循环结构 将绘制六边形的代码封装到了drawHexagon函数中,减少了重复代码的量。 7. 使用宏定义 将魔法数HEX_ANGLE和TURN_ANGLE定义为宏,提高了代码的可读性。 8. 使用函数封装 将绘制六边形的代码封装到了drawHexagon函数中,提高了代码的可读性和复用性。 9. 增加注释 在代码中增加了注释,能够更好地帮助理解代码的功能和逻辑。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值