解决一行最后一个字符是中文时乱码

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