| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2932 人关注过本帖, 2 人收藏
标题:在VC中直接写屏的方法
只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
结帖率:100%
收藏(2)
已结贴  问题点数:100 回复次数:32 
在VC中直接写屏的方法
为兼容vc6和C,以下代码用纯C旧语法:

程序代码:
#include <Windows.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <conio.h>

int main(void)
{
    HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
    const char* str = "Hello, 欢迎你进入编程论坛!";
    int length = strlen(str);
    CHAR_INFO* text = NULL;
    SMALL_RECT region;
    COORD bufferSize;
    COORD bufferCoord;
    int index;

    region.Top = 5;
    region.Left = 5;
    region.Bottom = region.Top + 4;
    region.Right = region.Left + 20;

    bufferSize.X = region.Right - region.Left + 1;
    bufferSize.Y = region.Bottom - region.Top + 1;

    bufferCoord.X = 0;
    bufferCoord.Y = 0;

    text = (CHAR_INFO*)calloc(bufferSize.X * bufferSize.Y, sizeof(CHAR_INFO));
    for (index = 0; index < bufferSize.X * bufferSize.Y; ++index)
    {
        if (index < length)
        {
            text[index].Char.AsciiChar = str[index];
            text[index].Attributes = (8 + (index + 1) % 6) + (4 << 4);
        }
        else
        {
            text[index].Char.AsciiChar = ' ';
            text[index].Attributes = 4 << 4;
        }
    }
    WriteConsoleOutputA(output, text, bufferSize, bufferCoord, &region);
    delete[] text;
    
    _getch();
    return EXIT_SUCCESS;
}


运行效果:
图片附件: 游客没有浏览图片的权限,请 登录注册

请留意:
1.画面中光标是没动的
2.文本有折行
3.中文可以半个字符变色

[ 本帖最后由 TonyDeng 于 2015-7-9 09:38 编辑 ]
2015-07-09 09:28
pycansi
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:5
帖 子:418
专家分:1060
注 册:2012-7-26
收藏
得分:10 
学习了


莫问前尘有愧,但求今生无悔
2015-07-09 09:48
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是引用边小白在2015-7-9 09:44:54的发言:


直接写屏是不是等于直接操作显存?这样就太强大了。

相当于DOS下直接操作显存。Windows与DOS不同,通常的程序是不允许直接操作硬件的(除非是写硬件驱动程序),这是调用Win32 API的方法,其实与DOS时代的调用中断差不多,不是直接写显存(Windows下不同显卡和显示模式下设备的显示内存入口不一定相同,是无法找到通用的显卡入口的),但却是在Windows下写控制台输出最快的方法。

授人以渔,不授人以鱼。
2015-07-09 09:50
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
下面是封装为函数的代码:

程序代码:
    // 功能:在指定矩形框中用默認屬性輸出ansi編碼文本(可折行)
    // 參數:text   - 輸出的文本字符串
    //       region - 輸出的矩形框
    // 返回:操作成功返回真否則為假
    bool MyConsole::OutputText(const std::string text, SMALL_RECT region)
    {
        WORD attr = GetTextAttribute();     // 獲取當前文本屬性

        // 屏幕塊的範圍
        COORD bufferSize;
        bufferSize.X = region.Right - region.Left + 1;
        bufferSize.Y = region.Bottom - region.Top + 1;

        // 輸出起始位置,為相對於bufferSize的左上角偏移量
        COORD bufferCoord;
        bufferCoord.X = 0;
        bufferCoord.Y = 0;

        BOOL success = FALSE;
        size_t length = bufferSize.X * bufferSize.Y;
        CHAR_INFO* const textBuffer = new CHAR_INFO[length];
        if (textBuffer)
        {
            for (size_t index = 0; index < length; ++index)
            {
                textBuffer[index].Char.AsciiChar = (index < text.size()) ? text[index] : ' ';
                textBuffer[index].Attributes = attr;
            }
            success = WriteConsoleOutputA(_output, textBuffer, bufferSize, bufferCoord, &region);
            delete[] textBuffer;
        }

        return (success == TRUE);
    }


这个抛去了字符自由变色的便利,只能用同一种属性。也可以用另一种封装方法,即在外面填写好textBuffer,再传参给函数。无论如何,都是以1楼的测试代码为基础的,搞明白了1楼的原理,想怎么做都可以。

授人以渔,不授人以鱼。
2015-07-09 10:01
w2009w
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:2
帖 子:190
专家分:542
注 册:2015-4-20
收藏
得分:10 
学得还没到这个程度
2015-07-09 10:02
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是引用边小白在2015-7-9 10:06:07的发言:

学习了!
想当年为糊口,帮人管理网吧,师傅反复叮咛我要为打游戏的升级directx,我问为什么,师傅说win不能直接操作显存,装direct可访问,提高游戏速度。后来拆装机多了,知道显存就是显卡上的一块块长方块,我还专门砸开看,什么都没发现。

现在DirectX升级到12版了,只能在Win10下运行。

授人以渔,不授人以鱼。
2015-07-09 10:14
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
控制台下的颜色值:
程序代码:
            static enum TextColor
            {
                Black = 0,              // 黑色
                Blue = 1,               // 藍色
                Green = 2,              // 綠色
                Cyan = 3,               // 青色
                Red = 4,                // 紅色
                Megenta = 5,            // 洋紅色
                Yellow = 6,             // 黃色
                White = 7,              // 白色
                Gray = 8,               // 灰色
                LightBlue = 9,          // 亮藍色
                LightGreen = 10,        // 亮綠色
                LightCyan = 11,         // 亮青色
                LightRed = 12,          // 亮紅色
                LightMegenta = 13,      // 亮洋紅色
                LightYellow = 14,       // 亮黃色
                LightWhite = 15         // 亮白色
            };


在控制台下,文本仅有16色(这是文本模式的规定,不同于图形态有256色以上直至真彩色,是文本模式与图形模式的本质区别,所谓文本程序,是指基于这种输出特点而言)。其用法是:属性(attribute)是8位整数,高4位为背景,低4位为前景,分别是上列的16色组合(2的4次方是16)。

授人以渔,不授人以鱼。
2015-07-09 10:29
hjx1120
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:李掌柜
等 级:贵宾
威 望:41
帖 子:1314
专家分:6927
注 册:2008-1-3
收藏
得分:10 

占个位!
2015-07-09 10:42
诸葛欧阳
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:流年
等 级:贵宾
威 望:82
帖 子:2790
专家分:14619
注 册:2014-10-16
收藏
得分:10 
学学

一片落叶掉进了回忆的流年。
2015-07-09 11:08
TAAAAB
Rank: 7Rank: 7Rank: 7
来 自:湖南
等 级:黑侠
威 望:1
帖 子:243
专家分:635
注 册:2011-5-29
收藏
得分:10 
收藏中,总有一天会看明白的

人有多懒,编程就有多难。
2015-07-09 11:21
快速回复:在VC中直接写屏的方法
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.073966 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved