БлогNot. coniow.h вместо conio.h

coniow.h вместо conio.h

Проблема с несовместимыми conio.h до сих пор часто всплывает при адаптации старых программ под Studio, применил вчера-сегодня вполне простое и адекватное решение.

Взять вот отсюда оба файла, включить в проект, заинклудить

#include "coniow.h"

вместо

#include <conio.h>

Конечно, рамочек из псевдографики в Юникодовском проекте не будет, придётся заменить на "*", к примеру. Ну и вставку asm {}, не работающую в Studio, убрать.

Для корректного отображения русских букв при выполнении программы нужно щелкнуть правой кнопкой мыши по заголовку консольного окна, в контекстом меню выбрать пункт "Свойства" и установить шрифт "Lucida Console" и желаемый размер шрифта. Далее нажать кнопку OK. В XP возникает диалог с 2-мя вариантами - нужно сохранить настройки для всех окон с тем же именем, чтобы не выполнять эту настройку повторно.

Также убедитесь, что файл действительно сохранён в Юникоде (UTF-8, кодовая страница 65001).

Ну и все возможные варианты русификации консоли тоже подключены :) В сумме, вот такой "борландовский консольный интерфейс" условно работает, исходник:

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <windows.h>
#include <locale.h>
#include "coniow.h"

typedef void (* FUN) (void);
 //Указатель на функцию void функция(void) - они будут выполнять пункты меню
typedef struct ITEM { //Структура для элемента меню
 int x,y; //Столбец и строка консоли, куда выводим строку меню
 char *str; //Наименование пункта меню
 FUN f; //Функция, привязанная к пункту меню
};
typedef struct WINDOW { //Окно вывода для всех функций
 int x1,y1,x2,y2,back,color; //Координаты двух углов, фоновый цвет, цвет вывода
};

void Exit () { //Восстановить консоль по умолчанию и выйти
 window (1,1,80,25); textbackground(BLACK); textcolor(LIGHTGRAY); clrscr(); exit(0);
}

void flush () { //Очистить буфер клавиатуры
 fflush(stdin);
}

void DrawWindow (WINDOW w) { //Нарисовать окно w
 char c[]={'+','=','+','!','!','+','=','+'};
 window (1,1,80,25); textbackground(w.back); textcolor(w.color);
 gotoxy (w.x1-1,w.y1-1);
 cprintf ("%c",c[0]);
 for (int i=w.x1; i<=w.x2; i++) cprintf ("%c",c[1]);
 cprintf ("%c",c[2]);
 for (int j=w.y1; j<=w.y2; j++) {
  gotoxy (w.x1-1,j); cprintf ("%c",c[3]);
  for (int i=w.x1; i<=w.x2; i++)  cprintf (" ");
  cprintf ("%c",c[4]);
 }
 gotoxy (w.x1-1,w.y2+1);
 cprintf ("%c",c[5]);
 for (int i=w.x1; i<=w.x2; i++) cprintf ("%c",c[6]);
 cprintf ("%c",c[7]);
}

void DrawMenu (int n,ITEM *m,WINDOW w) { //Управление меню
 int sel=0,back=WHITE,inactivecolor=DARKGRAY,activecolor=RED;
 DrawWindow (w); //Нарисовать окно
 textbackground(back); //Поставить цвет фона меню
 for (int i=0; i<n; i++) { //Вывести меню
  gotoxy(m[i].x,m[i].y);
  textcolor(inactivecolor);
  cprintf ("%s",m[i].str);
 }
 while (1) { //Бесконечный цикл обработки нажатий клавиш
  gotoxy(m[sel].x,m[sel].y);
  textcolor(activecolor);
  cprintf ("%s",m[sel].str); //Перепечатать активный пункт выделенным цветом
  flush(); //очистить буфер клавиатуры
  int ch=getch(); //Жд)м нажатия клавиши
  gotoxy(m[sel].x,m[sel].y); //Сбросили цвет активного пункта
  textcolor(inactivecolor);
  cprintf ("%s",m[sel].str);
  if (!ch) { //Это расширенный код?
   ch=getch(); //Прочитать его
   switch(ch) { //Обработка расширенных кодов клавиш
    case 72: case 75: if (sel) sel--; else sel=n-1; break; //Стрелки вверх и влево
    case 80: case 77: if (sel<n-1) sel++; else sel=0; break; //Стрелки вниз и вправо
   }
  }
  else { //Обработка не-расширенных кодов клавиш
   switch(ch) {
    case 13: //Нажата Enter
     textbackground(w.back); //Поставить фон и цвет окна функций
     textcolor(w.color);
     window (w.x1,w.y1,w.x2,w.y2); //Выводить будем в окно функций
     m[sel].f(); //Вызов функции, закрепленной за пунктом меню
     clrscr(); //Убрать, если не очищаем окно после выхода из функции
     textbackground(back); //Восстановить фон и окно во весь экран
     window (1,1,80,25);
    break;
    case 27: Exit(); //По Esc всегда выход из приложения
   }
  }
 }
}

//Ниже начинается часть пользователя

void File() { //Функция по меню File - пока ничего не делает
 long int i=0;
 //Печатать из функций лучше через cprintf
 while (!kbhit()) { delay (200); cprintf ("Работа функции File, шаг %ld\r\n",++i); }
}
void Do() { //Функция по меню Do - пока ничего не делает
 cprintf ("Введите целое число: ");
 int d;
 cscanf ("%d",&d); //Вводить из функций лучше через cscanf
 cprintf ("\r\nВы ввели значение %d\r\nНажмите клавишу для выхода...",d);
 getch(); getch();
}

void main () {
 setlocale (LC_ALL,"Russian");
 setlocale(LC_CTYPE, ".65001");
 SetConsoleCP(65001); 
 SetConsoleOutputCP(65001);
 
 //Пример для горизонтального меню
 ITEM menu1[3]={ //Описали меню
  {1,1,"File",File},
  {6,1,"Do",Do},
  {9,1,"Exit",Exit}
 };
 WINDOW w={3,3,77,23,BLUE,YELLOW}; //Описали окно вывода функций
 clrscr();
 DrawMenu (3,menu1,w); //Вызвали главную функцию системы
/*
//Пример для вертикального меню
 ITEM menu1[3]={ //Описали меню
  {2,2,"File",File},
  {2,3,"Do",Do},
  {2,4,"Exit",Exit}
 };
 WINDOW w={8,2,78,24,BLUE,YELLOW}; //Описали окно вывода функций
 textbackground (WHITE);
 clrscr();
 DrawMenu (3,menu1,w); //Вызвали главную функцию системы
 */
}

Оба файла в той версии, что использовал, архив .zip:

 Скачать coniow.h и coniow.c в архиве .zip (6 Кб)

P.S. Чтобы заработало под Studio 2015, отличающийся более строгими требованиями к неуправляемому коду, пришлось сделать следующее:

  • на всякий случай переименовал coniow.c в coniow.cpp;
  • поставил первой строкой coniow.cpp директиву
    #define _NO_CRT_SECURE_WARNINGS
  • в нескольких местах кода coniow.cpp заменил
    buffer = malloc ( ...

    на

    buffer = (CHAR_INFO*)malloc (

    т.е., выполнил явное приведение типа.

P.P.S. Прикреплённый ниже архив с coniow.c и coniow.h также работает в Visual Studio 2015, например, следующий исходник (main.cpp из архива):

#define _CRT_SECURE_NO_WARNING
#include <iostream>
#include "coniow.h"
using namespace std;

int main() {
 textbackground(BLUE); textcolor(YELLOW);
 clrscr();
 gotoxy(20 ,12);
 cprintf("Цветной экран как в старом Borland C++ :)");
 cin.sync(); cin.get();  return 0;
}

 coniow.zip, внутри папка с тремя файлами (6 Кб)

12.04.2015, 16:24 [12815 просмотров]


теги: c++ ретро studio

К этой статье пока нет комментариев, Ваш будет первым