일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- vscode
- InfluxDBClient
- Kotlin
- dictionary
- flutter
- C
- foreground service
- 문자열파싱
- InfluxDB
- FTP
- 콘솔 키보드 이벤트
- dart
- socket
- Linked List
- 파일입출력
- 문자열 다루기
- 코틀린
- 딕셔너리
- 문자열다루기
- Android
- 자료구조
- 진수변환기
- Mat 변수
- 메모리반환
- UI
- ws2_32.lib
- vs code
- background service
- 소켓프로그래밍
- 연결리스트
- Today
- Total
무슨 일로 C 하셨습니까?
[C] 소켓 프로그래밍::FTP - UI(1) 본문
안드로이드나 mfc, wpf 처럼 멋진 GUI를 만들면 좋겠지만
C에서는, 뭣보다 내가 원하는 바는 콘솔창에서 UI를 구현하는 것이다.
옛날 DOS 감성으로 문자로 UI를 그려서 구현하도록 하겠다.
#include <stdio.h>
#include <windows.h>
#include <io.h>
typedef struct _Painter {
struct _Line* line;
}Painter;
typedef struct _Line {
char* data;
struct _Line* next;
}Line;
아무래도 UI를 구현하게 된다면 고정적으로 출력되는 화면(문자열)이 존재할 것이다.
그러한 화면을 저장하기 위해 리스트 형식의 자료형을 선언하겠다.
void Painting(Painter Paint_) {
system("cls");
printf("파일 및 폴더 선택==============================\n");
PaintLine(Paint_, 0);
printf("\n↑,↓ : 이동/ Enter: 선택--------------------\n");
}
void PaintLine(Painter Paint_) {
// 커서 좌표 이동
COORD pos = { 0,2 };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
Line* line = Paint_.line;
while (1) {
if (line == NULL) {
puts("");
break;
}
else {
printf("[ ] %-75s\n", line->data);
line = line->next;
}
}
}
위와 같이 함수가 호출될 때마다 화면을 지우고 화면을 출력하는 식으로 만들면
의도한 대로 만들 수 있다.
이렇게 만든 화면에 이제 컨트롤 요소를 넣어주어야 한다.
int Curser_Run(Painter Paint_) {
int key;
int x = 1, y = 2;
Painting(Paint_);
int linenum = _LineCount(Paint_);
_RemoveCursur();
_Moving(x, y);
while (1) {
key = getch();
// 방향키 & 특수키
if (key == 224)
{
key = getch();
switch (key) {
case 72: // 상
if (y > 2){
y--;
_Moving(x, y);
}
break;
case 75: // 좌
break;
case 77: // 우
break;
case 80: // 하
if (y <= linenum){
y++;
_Moving(x, y);
}
break;
default:
//puts("그 외");
break;
}
}
}
}
2021.01.25 - [C -이걸 굳이?/유틸리티] - [C] 키보드 이벤트
[C] 키보드 이벤트
scanf() 함수를 쓰게되면 콘솔에 키보드 입력을 할 수 있다. 그러나 이러한 방식은 입력된 내용을 엔터 쳐서 넘기는 것인데 이러한 입력말고 콘솔창에서 키보드 입력에 즉각적으로 반응하도록 만
qwerty-ojjj.tistory.com
- 내부에 사용된 함수
void _Moving(int x_, int y_) {
static x = 1;
static y = 1;
// 이전 좌표에 내용 지움
COORD pos = { x,y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
printf(" ");
// 좌표 새로 지정
pos.X = x_;
pos.Y = y_;
// 현 좌표 저장
x = x_;
y = y_;
// 현 좌표에 내용 그리기
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 3);
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
printf("●");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
void _RemoveCursur() {
// 껌뻑껌뻑 커서 지움
CONSOLE_CURSOR_INFO cursorInfo = { 0, };
cursorInfo.dwSize = 1;
cursorInfo.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}
int _LineCount(Painter p) {
Line* ptr = p.line;
if (ptr == NULL) return 0;
int count = 0;
while (1) {
if (ptr == NULL) return count;
ptr = ptr->next;
count++;
}
}
잘 동작하는지 확인하기 위해서는 화면을 만들 필요가 있겠다.
#include "StringFunc.h"
void Painter_Input(Painter* Paint_, char* data_) {
Line* target = Paint_->line;
Line* pre = NULL;
while (1) {
if (target == NULL) {
target = (Line*)malloc(sizeof(Line));
target->data = StringCopy(data_);
target->next = NULL;
if (pre == NULL) {
Paint_->line = target;
}
else {
pre->next = target;
}
break;
}
pre = target;
target = target->next;
}
}
입력한 문자열을 화면으로 구성하는 함수를 만들었다.
void main() {
Painter* p = (Painter*)malloc(sizeof(Painter));
p->line = NULL;
Painter_Input(p, "a");
Painter_Input(p, "b");
Painter_Input(p, "c");
Painter_Input(p, "d");
Painter_Input(p, "e");
Painter_Input(p, "f");
Curser_Run(*p);
}
위와 같이 함수를 사용해서 실행시킬 수 있다.
화살표를 이용하여 좌표를 움직일 수 있다.( 아직 선택은 구현하지 않았다. )
그런데 이렇게 하면 항목에 따라서 화면의 크기가 바뀐다는 단점이 있다.
이러한 점을 보완해보자.
void PaintLine(Painter Paint_, int index) {
...
// 출력될 라인의 시작 인덱스로 포인터 이동
for (int i = 0; i < index; i++) {
line = line->next;
}
for(int i = 0 ; i <10;i++){
if (line == NULL)puts("");
...
}
출력을 시작할 항목의 위치를 지정.
Line을 출력하는 함수에 while문을 for문으로 변경하여 해당 위치에서 일정 갯수만큼만 출력하게한 후
int Curser_Run(Painter Paint_) {
...
int selected = 0;
while (1) {
...
case 72: // 상
// y가 이동할 수 있는 범위
// 2 <= y <= 11
if (selected > 0) {
selected--;
if (y > 2)
y--;
else
PaintLine(Paint_, selected);
_Moving(x, y);
}
break;
...
case 80: // 하
// linenum : 실제 수 [1부터 시작]
// selected : index [0부터 시작]
if (selected < linenum - 1) {
selected++;
if (y < 11)
y++;
else
PaintLine(Paint_, selected - 9);
_Moving(x, y);
}
break;
...
좌표를 움직이는 함수에 y좌표 외 선택항목을 나타내는 변수를 활용하여
10번째 항목 외 항목을 선택할 수 있도록 만든다.
'C - 이걸 굳이? > FTP' 카테고리의 다른 글
[C] 소켓 프로그래밍::FTP - UI(2) (0) | 2021.04.25 |
---|---|
[C] 소켓 프로그래밍::FTP - 디렉토리 (0) | 2021.01.11 |
[C] 소켓 프로그래밍::FTP - 파일 전송 (1) | 2020.12.10 |
[C] 소켓 프로그래밍::FTP - 연결 (0) | 2020.12.04 |
[C] 소켓 프로그래밍::FTP (0) | 2020.12.03 |