wxWidgets의 textCtrl에 실행 취소(Undo)와 같이 다시 실행(Redo)가 존재한다.

이걸 이용해서 구현이 가능하다.

 

Redo를 하기 위한 이벤트 핸들러를 추가하자.

 wxMain.h

1
2
3
4
5
    // Edit 메뉴에 적용할 이벤트 핸들러
    void OnUndo(wxCommandEvent& event);
    void OnRedo(wxCommandEvent& event);
    void OnSelectAll(wxCommandEvent& event);
    void OnInsertDateTime(wxCommandEvent& event);
cs

 

Undo와 같이 Redo가 가능할 경우에 활성화를 할수 있게. 선언하자.

 wxMain.h

1
2
3
    // 메뉴 동적 활성화 하기 위한 이벤트 핸들러
    void OnUpdateUndo(wxUpdateUIEvent& event);
    void OnUpdateRedo(wxUpdateUIEvent& event);
cs

 

이제 wxMain.cpp에 작업을 하자.

먼저 메뉴를 추가하자.

wxMain.cpp

1
2
3
4
5
6
7
    m_menuEdit = new wxMenu;
    m_menuEdit->Append(wxID_UNDO, "&Undo\tCtrl+Z""Undo the last action");
    m_menuEdit->Append(wxID_REDO, "&Redo\tCtrl+Y""Redo the last undone action");
    m_menuFile->AppendSeparator();
    m_menuEdit->Append(ID_SELECT_ALL, "&Select All\tCtrl+A""Select all text");
    m_menuFile->AppendSeparator();
    m_menuEdit->AppendCheckItem(ID_DATETIME, "&DateTime\tF5""DateTime");
cs

 

정의 및 이벤트 핸들러를 연결한다.

wxMain.cpp

1
2
3
4
5
6
7
8
9
10
    // 메뉴 Edit에 관련된 이벤트 핸들러
    Bind(wxEVT_MENU, &MyFrame::OnUndo, this, wxID_UNDO);
    Bind(wxEVT_MENU, &MyFrame::OnRedo, this, wxID_REDO);
    Bind(wxEVT_MENU, &MyFrame::OnInsertDateTime, this, ID_DATETIME);
    Bind(wxEVT_MENU, &MyFrame::OnSelectAll, this, ID_DATETIME);
 
 
    // 메뉴바 갱신 이벤트 핸들러
    Bind(wxEVT_UPDATE_UI, &MyFrame::OnUpdateUndo, this, wxID_UNDO);
    Bind(wxEVT_UPDATE_UI, &MyFrame::OnUpdateRedo, this, wxID_REDO);
cs

 

메뉴와 메뉴바 갱신에 관련된 이벤트 핸들러를 정의한다.

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
void MyFrame::OnUndo(wxCommandEvent& event) {
    if (m_textControl->CanUndo()) {
        m_textControl->Undo();
    }
}
 
void MyFrame::OnRedo(wxCommandEvent& event)
{
    if (m_textControl->CanRedo())
    {
        m_textControl->Redo();
    }
}
 
// 메뉴바 갱신 이벤트 핸들러
void MyFrame::OnUpdateUndo(wxUpdateUIEvent& event)
{
    event.Enable(m_textControl->CanUndo());
}
 
// 메뉴바 갱신 이벤트 핸들러
void MyFrame::OnUpdateRedo(wxUpdateUIEvent& event)
{
    event.Enable(m_textControl->CanRedo());
}
cs

 

이렇게하면, 다시 시작을 구현할 수 있다.

 

Posted by JunkMam
,

 C에서는 수를 정의 하거나, 값을 저장할 수 있는 기능을 제공한다.

 C에서는 수를 정의하는 것으로는 매크로라는 것으로

 '#define'을 사용한다.

1
2
3
 
#define PI 3.14
#define POW(x) ((x)*(x))
cs

 

이렇게 사용이 가능하다.

PI는 3.14라는 상수를 정의해주고, POW라는 것은 제곱을 표현하게 된다.

 

매크로는 특정 문자을 복사해서 덮어 씌우는 것으로 다음과 적용하는 것과 동일하게 할 수 있다.

 

1
2
3
4
5
6
7
8
#define PI 3.14
 
int main(int argc, char** argv){
    3.14+1;
    PI+1;
 
    return 0;
}
cs

 

3.14+1과 PI+1은 동일한 결과물을 가진다.

그렇다면, 매크로를 사용하는 이유가 무엇일까?

예을 들어서 (x+1)(x+2)...(x+100)이런식의 글을 작성되어 있다고 한다면,

x = 1일때, (1+1)(1+2)...(1+100)이렇게 가능하듯이.

#define X라는 것을 정의 해놓는다고 한다면,

(X+1)(X+2)...(X+100)이렇게 되었을때,

#define X 1

 

이렇게 하면, X=1일때 이런식으로 선언해서 사용할 수 있게 되는 것이다.

즉, 반복적으로 사용될 '상수'를 정의내려서 적용할 수 있다.

반대로 특정 연산을 정의 내려서 처리할 수 있다.

위에 작성한

#define POW(x)가 그것이다.

여기서 POW(x)는 '매크로 함수'라고 칭하며, 함수처럼 x라는 매개 변수를 받아서 '연산'을 복사한다.

 

단순한 연산이지만 자주 사용될 '연산'은 '매크로 함수'를 사용해서 컴파일러가 자동으로 복사 할 수 있다.

 

C는 계산한 결과를 저장하는 기능도 제공해준다.

이걸 '변수'라고 칭하며, 종류를 정해져있다.

C에서 기본적으로 제공해주는 '변수'의 종류는 다음과 같다.

 

변수 유형 설명 범위 예시
char 단일 문자를 저장하거나, 정수형으로 데이터 최소 단위이다. -128 ~ 127 char ch = 'A';
char baseNum = 200;
int 정수를 저장하는 기본 데이터 유형 Bit에 따라서 범위가 달라짐.
16Bit: -32768 ~ 32767
32Bit: -2147483648 ~ 2147483647
int num = 100;
flaot 실수를 저장하는데 사용되며, 단정밀도 부동 소수점 수를 나타낸다. 1.175494351 E - 38 ~ 3.402823466 E + 38 float realNum = 3.14f;
double 실수를 저장하는데 사용되며, 배정밀도 부동 소수점 수를 나타낸다. 2.2250738585072014 E - 308 ~ 1.7976931348623158 E + 308 double realNums = 3.14;
short 정수를 저장하는 데이터 유형. int보다 적은 범위를 저장한다.
16bit일때랑 똑같다.
-32768 ~ 32767 short num = 100;
long 정수를 저장하는 데이터 유형.
int보다 큰 범위를 저장한다.
64bit이상일때 사용됨.
-2,147,483,648 ~ 2,147,483,647 long num = 100;

 

 

여기서 접두사가 무엇이 붙냐에 따라서 변수의 상태가 달라지는 경우가 있다.

예을 들어서 unsigned가 있다.

unsigned란, 부호가 존재하지 않는 것으로 변수 유형에서 범위를 무조건 상수로 적용된 상태를 뜻한다

unsigned char라면, 0~255까지 지원하는 것 처럼 적용이 된다.

 

C와 C++같은 언어들은 컴파일러마다 다르지만, 실수랑 정수를 그냥 연산할 경우 정수 기준으로 계산이 되어서 결과를 저장하는 경우가 있다.

 

예을 들어서 int a = 1; float b = 3.14f;라는게 있다면,

a+b를 하면, 4가 결과물로 저장하게 된다.

이 경우 (a*1.0)+b을 사용해줘야한다.

 

예을 들어서 다음과 같이 적용했는데. 소수점이 0이 된다면, 컴파일러와 CPU가 그것을 지원해주지 않는 경우라고 이해하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 
#define PI 3.14
 
int main() {
    int a = 1;
    float b = PI;
 
    float c = a+b;
    float d = (a*1.0)+b;
 
    printf("%f\n", c);
    printf("%f\n", d);
 
    return 0;
}
 
cs

 

'프로그래밍 > C 언어' 카테고리의 다른 글

[C] 제어(1) - 조건문 -  (0) 2024.02.17
[C] 연산자  (0) 2024.02.16
[C] 기본적으로 지원해주는 출력  (0) 2024.02.14
[C] 기본 구조  (1) 2024.02.13
Posted by JunkMam
,

 wxWidgets에서 글을 작성한 후에 실행 취소를 하는 기능을 제공해보자.

 실행 취소(Undo)는 wxWidgets에서 ID를 지원해주기 때문에 wxMain.h에서 ID을 추가할 필요없다.

 

 그래서 이벤트 핸들러만 제작하면 되는데.

 wxMain.h에 다음과 같이 추가해주자.

1
2
3
4
5
6
 
    // Edit 메뉴에 적용할 이벤트 핸들러
    void OnUndo(wxCommandEvent& event);
    void OnSelectAll(wxCommandEvent& event);
    void OnInsertDateTime(wxCommandEvent& event);
 
cs

 

이후에 Edit의 하위 메뉴를 추가하주자.

1
2
3
4
5
6
    m_menuEdit = new wxMenu;
    m_menuEdit->Append(wxID_UNDO, "&Undo\tCtrl+Z""Undo the last action");
    m_menuFile->AppendSeparator();
    m_menuEdit->Append(ID_SELECT_ALL, "&Select All\tCtrl+A""Select all text");
    m_menuFile->AppendSeparator();
    m_menuEdit->AppendCheckItem(ID_DATETIME, "&DateTime\tF5""DateTime");
cs

 

이 후에 이벤트 핸들러랑 연결될 수 있게 적용해준다.

1
2
3
4
    // 메뉴 Edit에 관련된 이벤트 핸들러
    Bind(wxEVT_MENU, &MyFrame::OnUndo, this, wxID_UNDO);
    Bind(wxEVT_MENU, &MyFrame::OnInsertDateTime, this, ID_DATETIME);
    Bind(wxEVT_MENU, &MyFrame::OnSelectAll, this, ID_DATETIME);
cs

 

이렇게 하면, 이벤트 핸들러인 OnUndo랑 연동된다.

이제 OnUndo를 정의해주면, 실행 취소가 가능하다.

여기서 실행 취소는 wxTextCtrl에서 실행 취소 기능을 지원해주기 때문에 OnUndo는 그걸 이용하면 된다.

1
2
3
4
5
6
void MyFrame::OnUndo(wxCommandEvent& event) {
    if (m_textControl->CanUndo()) {
        m_textControl->Undo();
    }
}
 
cs

 

실행 취소가 활성화 비활성화로 실행이 존재할 경우에 활성화되고 그런것이 전혀 없다면, 실행 취소를 비활성화 시키는 방식을 구현하기 위해서는 메뉴 항목의 상태를 동적으로 업데이트하는 장치가 필요하다.

wxWidgets에서는 'wxUpdateUIEvent'라는 기능을 지원해준다.

이걸 이용하는 방법을 위해서

wxMain.h에 이벤트 핸들러를 선언한다.

1
2
    // 메뉴 동적 활성화 하기 위한 이벤트 핸들러
    void OnUpdateUndo(wxUpdateUIEvent& event);
cs

 

 

wxMain.cpp에서 OnUpdateUndo라는 이벤트 핸들러를 wxEVT_UPDATE_UI 종류로 연결시켜준다.

1
2
    // 메뉴바 갱신 이벤트 핸들러
    Bind(wxEVT_UPDATE_UI, &MyFrame::OnUpdateUndo, this, wxID_UNDO);
cs

 

이렇게 해서 wxMain.h에 선언했던 'OnUpdateUndo'를 정의해준다.

1
2
3
4
5
// 메뉴바 갱신 이벤트 핸들러
void MyFrame::OnUpdateUndo(wxUpdateUIEvent& event)
{
    event.Enable(m_textControl->CanUndo());
}
cs

 

 실행취소가 가능할때 활성화되고,실행취소가 불가능하면 비활성화를 적용이 가능해진다.

 

Posted by JunkMam
,