解决一行最后一个字符是中文时乱码
This commit is contained in:
@@ -12,33 +12,38 @@
|
|||||||
## 开发环境
|
## 开发环境
|
||||||
  Windows,Visual Studio 2017
|
  Windows,Visual Studio 2017
|
||||||
|
|
||||||
## 说明
|
## 注意事项
|
||||||
  需要注意的是,窗格只是逻辑意义上的窗格,它们属于同一个控制台窗口,共享输入缓冲区,因此这个库仅**适用于需要多个窗格用于输出**而不超过1个窗格同时用来输入。
|
  需要注意的是,窗格只是逻辑意义上的窗格,它们属于同一个控制台窗口,共享输入缓冲区,因此这个库仅**适用于需要多个窗格用于输出**而不超过1个窗格同时用来输入。
|
||||||
|
|
||||||
  构建这个库的初衷是为了方便某些高级语言操作控制台,因此将它的导出函数的参数都设定为简单的数值型和字符串,避免在高级语言中额外定义数据类型,方便使用。
|
  分隔线是需要占用空间的,由于制表符是双字节字符,因此分隔线长度必须是2的倍数。同时注意,水平分割线的**高度**是1个字符,而**垂直分隔线的宽度是2个字符**。
|
||||||
|
|
||||||
|
  构建这个库的初衷是为了方便某些高级语言操作控制台,因此没有导出类而是封装了一系列C函数,并将它们的参数都设定为简单的数值型和字符串,避免在高级语言中额外定义数据类型,方便使用。
|
||||||
|
###   **你不应该直接操作ConsoleWindow、Pannel、和Spliter类对象**,而应仅将它们的指针作为参数传递。
|
||||||
|
|
||||||
  此库通过调用Windows API实现,因此仅适用于Windows系统。
|
  此库通过调用Windows API实现,因此仅适用于Windows系统。
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
* ### C/C++
|
||||||
|
将conctrl.dll和conctrl.h放到同一目录;
|
||||||
|
|
||||||
|
* ### 其他语言
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 导出函数列表
|
||||||
|
|
||||||
|
|
||||||
## 缺陷
|
## 缺陷
|
||||||
* 对用户输入的控制比较无力
|
* 对用户输入的控制比较无力
|
||||||
* 只能对整行设定字符样式
|
* 只能对整行设定字符样式
|
||||||
* 其他
|
* 其他
|
||||||
|
|
||||||
## 使用示例
|
|
||||||
* ### C/C++
|
|
||||||
|
|
||||||
* ### 其他语言
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 函数列表
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 辅助资料
|
## 辅助资料
|
||||||
<a name="constant"> </a>
|
<a name="constant"> </a>
|
||||||
|
|
||||||
### Windows控制台字符样式常量
|
### Windows控制台字符样式常量
|
||||||
|
定义于consoleapi2.h,使用引入windows.h或自定义
|
||||||
```C
|
```C
|
||||||
#define FOREGROUND_BLUE 0x0001 // text color contains blue.
|
#define FOREGROUND_BLUE 0x0001 // text color contains blue.
|
||||||
#define FOREGROUND_GREEN 0x0002 // text color contains green.
|
#define FOREGROUND_GREEN 0x0002 // text color contains green.
|
||||||
@@ -59,4 +64,4 @@
|
|||||||
```
|
```
|
||||||
|
|
||||||
## 项目地址
|
## 项目地址
|
||||||
[https://github.com/mattuy/conctrl.git](https://github.com/mattuy/conctrl.git)
|
[https://github.com/mattuylee/conctrl.git](https://github.com/mattuylee/conctrl.git)
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "console_window.h"
|
||||||
|
#include "pannel.h"
|
||||||
|
#include "spliter.h"
|
||||||
|
#include "coding.h"
|
||||||
#include "conctrl.h"
|
#include "conctrl.h"
|
||||||
|
|
||||||
//创建当前控制台窗口对应的控制窗口
|
//创建当前控制台窗口对应的控制窗口
|
||||||
|
|||||||
@@ -18,5 +18,3 @@ FocusOnPannel
|
|||||||
CreateSpliter
|
CreateSpliter
|
||||||
DestroySpliter
|
DestroySpliter
|
||||||
MoveSpliter
|
MoveSpliter
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+3
-5
@@ -1,13 +1,11 @@
|
|||||||
// ConsoleController
|
// ConsoleController
|
||||||
// 2018-11-28
|
// 2018-11-28
|
||||||
// By Mattuy
|
// By Mattuy
|
||||||
|
|
||||||
#ifndef _HEAD_CONSOLE_CONTROLLER_
|
#ifndef _HEAD_CONSOLE_CONTROLLER_
|
||||||
#define _HEAD_CONSOLE_CONTROLLER_
|
#define _HEAD_CONSOLE_CONTROLLER_
|
||||||
#include "console_window.h"
|
class ConsoleWindow;
|
||||||
#include "pannel.h"
|
class Pannel;
|
||||||
#include "spliter.h"
|
class Spliter;
|
||||||
#include "coding.h"
|
|
||||||
/**
|
/**
|
||||||
* 创建控制台控制器
|
* 创建控制台控制器
|
||||||
* @return value, 指向当前控制台的控制台操作对象的指针,作为其他函数的参数,以通过它控制
|
* @return value, 指向当前控制台的控制台操作对象的指针,作为其他函数的参数,以通过它控制
|
||||||
|
|||||||
+10
-2
@@ -33,8 +33,8 @@
|
|||||||
<ClInclude Include="spliter.h" />
|
<ClInclude Include="spliter.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Include="..\README.md" />
|
||||||
<None Include="conctrl.def" />
|
<None Include="conctrl.def" />
|
||||||
<None Include="README.md" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<VCProjectVersion>15.0</VCProjectVersion>
|
<VCProjectVersion>15.0</VCProjectVersion>
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
@@ -95,6 +95,9 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<ModuleDefinitionFile>conctrl.def</ModuleDefinitionFile>
|
||||||
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@@ -103,6 +106,9 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<ModuleDefinitionFile>conctrl.def</ModuleDefinitionFile>
|
||||||
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@@ -116,6 +122,7 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<ModuleDefinitionFile>conctrl.def</ModuleDefinitionFile>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@@ -130,6 +137,7 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<ModuleDefinitionFile>conctrl.def</ModuleDefinitionFile>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|||||||
@@ -49,10 +49,10 @@
|
|||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="conctrl.def">
|
<None Include="..\README.md">
|
||||||
<Filter>Resource Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="README.md">
|
<None Include="conctrl.def">
|
||||||
<Filter>Resource Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
+9
-8
@@ -65,7 +65,7 @@ void Pannel::Move(SMALL_RECT rect) {
|
|||||||
*/
|
*/
|
||||||
void Pannel::AddText(std::string text, int attribute) {
|
void Pannel::AddText(std::string text, int attribute) {
|
||||||
//将要添加的文本与最后一行拼接。否则每次调用本函数将直接写到新行
|
//将要添加的文本与最后一行拼接。否则每次调用本函数将直接写到新行
|
||||||
if (this->lines.size() > 0 && this->isTrueLine(lines.back())) {
|
if (this->lines.size() > 0 && !this->isTrueLine(lines.back())) {
|
||||||
text = this->lines.back().text + text;
|
text = this->lines.back().text + text;
|
||||||
lines.pop_back();
|
lines.pop_back();
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ void Pannel::Flush() {
|
|||||||
if (this->lines.size() == 0) return; //空缓冲区
|
if (this->lines.size() == 0) return; //空缓冲区
|
||||||
//获取迭代起点
|
//获取迭代起点
|
||||||
std::vector<Line>::iterator iter;
|
std::vector<Line>::iterator iter;
|
||||||
if (this->lines.size() <= lineCount) {
|
if (this->lines.size() <= (size_t)lineCount) {
|
||||||
iter = this->lines.begin();
|
iter = this->lines.begin();
|
||||||
} //显示所有行
|
} //显示所有行
|
||||||
else if (this->from < 0 || this->from >= this->lines.size()) {
|
else if (this->from < 0 || this->from >= this->lines.size()) {
|
||||||
@@ -113,7 +113,7 @@ void Pannel::Flush() {
|
|||||||
} //显示特定屏
|
} //显示特定屏
|
||||||
//写文本行
|
//写文本行
|
||||||
COORD lineStart = { 0, 0 };
|
COORD lineStart = { 0, 0 };
|
||||||
for (size_t i = 0; i < lineCount; i++) {
|
for (size_t i = 0; i < (size_t)lineCount; i++) {
|
||||||
DWORD writtenCount;
|
DWORD writtenCount;
|
||||||
//获取除去换行符的字符长度
|
//获取除去换行符的字符长度
|
||||||
int length = iter->text.size();
|
int length = iter->text.size();
|
||||||
@@ -138,11 +138,11 @@ bool Pannel::ScrollForward(int lineCount) {
|
|||||||
int to = this->from;
|
int to = this->from;
|
||||||
if (this->from < 0 || lineCount < 0) return false;
|
if (this->from < 0 || lineCount < 0) return false;
|
||||||
else to += lineCount;
|
else to += lineCount;
|
||||||
return ScrollTo(to < this->lines.size() ? to : -1);
|
return ScrollTo(to < (int)this->lines.size() ? to : -1);
|
||||||
}
|
}
|
||||||
//滚到
|
//滚到
|
||||||
bool Pannel::ScrollTo(int line) {
|
bool Pannel::ScrollTo(int line) {
|
||||||
if (line >= this->lines.size()) return false;
|
if (line >= (int)this->lines.size()) return false;
|
||||||
int to = line < 0 ? -1 : line;
|
int to = line < 0 ? -1 : line;
|
||||||
if (this->from != to) {
|
if (this->from != to) {
|
||||||
this->from = to;
|
this->from = to;
|
||||||
@@ -164,7 +164,7 @@ bool Pannel::Focus(COORD _coord){
|
|||||||
return SetConsoleCursorPosition(this->window->hOutput, coord);
|
return SetConsoleCursorPosition(this->window->hOutput, coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
//将文本分割为若干行。
|
//将文本分割为若干行,至少保证一行
|
||||||
std::vector<std::string> Pannel::splitToLines(std::string _text) {
|
std::vector<std::string> Pannel::splitToLines(std::string _text) {
|
||||||
int charCount = this->area.Right - this->area.Left + 1;
|
int charCount = this->area.Right - this->area.Left + 1;
|
||||||
if (charCount <= 0) {
|
if (charCount <= 0) {
|
||||||
@@ -178,12 +178,13 @@ std::vector<std::string> Pannel::splitToLines(std::string _text) {
|
|||||||
do {
|
do {
|
||||||
int i;
|
int i;
|
||||||
line = "";
|
line = "";
|
||||||
for (i = 0; i < charCount; i++) {
|
for (i = 0; text[start + i] && i < charCount; i++) {
|
||||||
if (!text[start + i]) break; //文本结尾
|
|
||||||
if (text[start + i] == '\r' || text[start + i] == '\n') {
|
if (text[start + i] == '\r' || text[start + i] == '\n') {
|
||||||
line += "\r\n";
|
line += "\r\n";
|
||||||
break;
|
break;
|
||||||
} //自然换行的行尾保留换行符
|
} //自然换行的行尾保留换行符
|
||||||
|
//行最后一个字符无法显示双字节字符
|
||||||
|
if (i == charCount - 1 && text[i + start] > 127) break;
|
||||||
line += text[i + start];
|
line += text[i + start];
|
||||||
} //扫描一行(已计算边框)
|
} //扫描一行(已计算边框)
|
||||||
//过滤换行符
|
//过滤换行符
|
||||||
|
|||||||
+2
-2
@@ -32,9 +32,9 @@ void Spliter::draw(bool clear) {
|
|||||||
//取步进方向
|
//取步进方向
|
||||||
SHORT* direct = this->verticle ? &curPosition.Y : &curPosition.X;
|
SHORT* direct = this->verticle ? &curPosition.Y : &curPosition.X;
|
||||||
//画分割线
|
//画分割线
|
||||||
for (SHORT i = 0; i < this->length; i++) {
|
for (; *direct < this->length; ) {
|
||||||
FillConsoleOutputAttribute(this->window->hOutput, this->attribute, 2, curPosition, &written);
|
FillConsoleOutputAttribute(this->window->hOutput, this->attribute, 2, curPosition, &written);
|
||||||
WriteConsoleOutputCharacter(this->window->hOutput, spliter, 2, curPosition, &written);
|
WriteConsoleOutputCharacter(this->window->hOutput, spliter, 2, curPosition, &written);
|
||||||
this->verticle ? curPosition.Y += 2 : curPosition.X += 2;
|
this->verticle ? curPosition.Y += 1 : curPosition.X += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include "conctrl.h"
|
|
||||||
int main() {
|
|
||||||
ConsoleWindow* window = CreateConsoleWindow(80, 40);
|
|
||||||
Pannel* writePannel = window->CreatePannel({ 0, 0, 79, 24 });
|
|
||||||
Pannel* messagePannel = window->CreatePannel({ 0, 26, 79, 39 });
|
|
||||||
Spliter* spliter = window->CreateSpliter({ 0, 25 }, 80, false, FOREGROUND_GREEN);
|
|
||||||
messagePannel->AddLine("hello world.");
|
|
||||||
writePannel->Focus({ 0,0 });
|
|
||||||
getchar();
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user