이전에 저장 기능에서 파일 경로를 새로 불러오는 경우가 불편해서 뺏다면, 이번엔 다른 이름으로 저장해야되는 경우가 생길 수 있다.

 이걸 구현하기 위해서 메뉴를 추가해줘야한다.

wxMain.h

1
2
3
4
5
6
7
8
enum
{
    ID_QUIT,
    ID_SAVE_AS,
    ID_WordWarp,
    ID_FontSetting,
    ID_StatusBar,
};
cs

 

 

 이렇게 해서 ID을 추가하고,

 

Bind로 연결될 이벤트 핸들러 메소드를 선언해준다.
OnSaveAs을 wxMain.h에 추가해준다.

 

wxMain.h

1
2
3
    void OnOpen(wxCommandEvent& event);
    void OnSave(wxCommandEvent& event);
    void OnSaveAs(wxCommandEvent& event);
cs

 

 

이 후에 wxMain.cpp에서 메뉴를 추가하는 기능을 정의하며, 이벤트 핸들러를 정의 및 연결해줘야한다.

wxMain.cpp

1
2
3
4
5
6
7
8
    m_menuFile = new wxMenu;
    m_menuFile->Append(wxID_NEW, "&New\tCtrl-N""New a Notepad");
    m_menuFile->Append(ID_NEW_WINDOW, "&New Windows\tCtrl+Shift+N""Open a new window.");
    m_menuFile->Append(wxID_OPEN, "&Open\tCtrl-O""Open a file");
    m_menuFile->Append(wxID_SAVE, "&Save\tCtrl-S""Save the file");
    m_menuFile->Append(ID_SAVE_AS, "Save &As\tCtrl-A""Save the file");
    m_menuFile->AppendSeparator();
    m_menuFile->Append(ID_QUIT, "E&xit\tAlt-X""프로그램 종료");
cs

 

이렇게 메뉴를 추가한다.

 Append(ID_SAVE_AS, "Save &As\tCtrl-A", "Save the file");을 이용해서 메뉴를 추가해준다.

 

 이 후에 이벤트 핸들러를 연결해준다.

wxMain.cpp

1
2
3
    Bind(wxEVT_MENU, &MyFrame::OnOpen, this, wxID_OPEN);
    Bind(wxEVT_MENU, &MyFrame::OnSave, this, wxID_SAVE);
    Bind(wxEVT_MENU, &MyFrame::OnSaveAs, this, ID_SAVE_AS);
cs

 

Bind을 이용해서 설정해놓은 ID_SAVE_AS에 연결이 되었으니.

OnSaveAs라는 함수를 정의 해줘야한다.

wxMain.cpp

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
31
32
33
34
35
36
void MyFrame::OnSaveAs(wxCommandEvent& event)
{
    wxFileDialog saveFileDialog(this, _("Save TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
 
    wxString saveAsFileName;
    wxString saveAsFilePath;
 
    switch (saveFileDialog.ShowModal()) {
    case wxID_OK: {
        saveAsFileName = saveFileDialog.GetFilename();
        saveAsFilePath = saveFileDialog.GetPath();
        break;
    }
    case wxID_CANCEL: {
        return;
    }
    }
 
    // 사용자가 선택한 파일 경로를 저장합니다.
    if (!m_textControl->SaveFile(saveAsFilePath))
    {
        wxMessageBox("Could not save the file!""Error", wxOK | wxICON_ERROR);
        return;
    }
 
    // 파일이 성공적으로 저장되었다면, 현재 파일 경로를 업데이트하고 타이틀을 설정합니다.
    m_currentFileName = saveAsFileName;
    m_currentFilePath = saveAsFilePath;
    wxString titleNames = m_currentFileName;
    SetTitle(titleNames + " - Notepad"); // 타이틀 업데이트
 
    // 상태 표시줄에 메시지를 표시합니다.
    SetStatusText("File saved successfully.");
}
 
cs

 

 이렇게 해서 메시지를 표시 및 적용할 수 있게 된다.

 

 

Posted by JunkMam
,

 wxWidgets에서 열거나 저장한 후에 파일에서 저장을 매번 경로를 지정해줘야하는 문제점이 있다.

 이 점을 개선하기 위해서 저장의 경로를 저장해놓아야 되는 경우가 생긴다.

 경로를 저장하기 위해서 wxMain.h을 다음과 같이 수정한다.

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#pragma once
#include "wx/wx.h"
#include <wx/filedlg.h>
#include <wx/textctrl.h>
#include <wx/splitter.h>
 
// Font Dialog
#include <wx/fontdlg.h>
 
// 파일을 읽어 들이기 위한 용도.
#include <fstream>
#include <sstream>
 
#include "wxOptionsDialog.h"
 
enum
{
    ID_QUIT,
    ID_WordWarp,
    ID_FontSetting,
    ID_StatusBar,
};
 
enum {
    MY_EVENT_ID = 10001,
};
 
// 메뉴 항목 ID 정의
enum
{
    ID_NEW_WINDOW = wxID_HIGHEST + 1 // 새 창을 위한 고유 ID
};
 
class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};
 
class MyFrame : public wxFrame
{
public:
    MyFrame(const wxString& title);
 
    void OnQuit(wxCommandEvent& event);
 
private:
    wxTextCtrl* m_textControl;
 
    // 현재 파일의 경로를 저장하는 변수
    wxString m_currentFileName;
    wxString m_currentFilePath;
 
 
    //wxOptionDialog* m_dialog;
    wxFont* m_font;
 
    wxStatusBar* m_statusBar;
 
    // 메뉴바 및 메뉴 변수.
    wxMenuBar* m_menuBar;
    wxMenu* m_menuFile;
    wxMenu* m_menuFormat;
    wxMenu* m_menuView;
 
    void OnNew(wxCommandEvent& event);
    void OnNewWindow(wxCommandEvent& event);
    void OnOpen(wxCommandEvent& event);
    void OnSave(wxCommandEvent& event);
    void OnButtonClick(wxCommandEvent& event);
 
    // Format 메뉴에 적용할 이벤트 핸들러
    void OnToggleWordWrap(wxCommandEvent& event);
    void OnFontSetting(wxCommandEvent& event);
 
    // View 메뉴에 적용할 이벤트 핸들러
    void OnToggleStatusBar(wxCommandEvent& event);
 
 
    // 이벤트를 받기 위한 메소드
    void OnMyCustomEvent(MyCustomEvent& event);
};
 
cs

 

 여기서 열어둔 파일들의 경로와 이름을 저장하기 위해서

 wxString m_currentFileName; // 현재 파일 이름

 wxString m_currentFilePath; // 현재 파일 경로

 

 이 2개를 추가했다.

 

 이 후에 wxMain.cpp에 있는 OnSave이라는 이벤트 핸들러를 다음과 같이 수정한다.

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
31
32
33
34
35
 
void MyFrame::OnSave(wxCommandEvent& event)
{
    wxFileDialog saveFileDialog(this, _("Save TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
 
    // 경로가 비어있는 경우엔.
    if (m_currentFilePath.IsEmpty()) {
        switch (saveFileDialog.ShowModal()) {
        case wxID_CANCEL: {
            return;
        }
 
        case wxID_OK: {
            m_currentFileName = saveFileDialog.GetFilename();
            // 세이브 및 적용이 완료했을 경우.
            m_currentFilePath = saveFileDialog.GetPath();
            break;
        }
        }
    }
 
    // 현재 텍스트 컨트롤의 내용을 파일에 저장합니다.
    if (!m_textControl->SaveFile(m_currentFilePath)) {
        // 현재 텍스트의 내용을 파일에 저장하지 못한다면.
        wxMessageBox("Could Not save the File!""Error", wxOK);
        return;
    }
 
    wxString titleNames = m_currentFileName;
    titleNames += " - Notepad";
    // 타이틀을 열린 파일의 이름으로 설정합니다.
    SetTitle(titleNames);
}
 
cs

 

 m_currentFilePath의 내용이 비어 있다면, 저장 경로를 받기 위해서 saveFileDialog.ShowModel을 하여, 경로를 제공 받게 한다.

 OK을 눌렀을 경우에 saveFileDialog에 파일 이름과 파일 경로를 각각 m_currentFileName과 m_currentFilePath에 저장하도록 한다.

 저장이 실패했을 경우엔 제대로 파일에 저장을 하지 못했다는 정보를 알려준다.

 여기서 실패했을 경우에 다시 경로를 찾아 가야도록 해야되므로

 

 지역 변수를 이용해서 적용하는 방법도 있다.

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
31
32
33
34
35
36
37
38
39
40
41
 
void MyFrame::OnSave(wxCommandEvent& event)
{
    wxFileDialog saveFileDialog(this, _("Save TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
 
    wxString saveFileName = m_currentFileName;
    wxString saveFilePath = m_currentFilePath;
 
    // 경로가 비어있는 경우엔.
    if (m_currentFilePath.IsEmpty()) {
        switch (saveFileDialog.ShowModal()) {
        case wxID_CANCEL: {
            return;
        }
 
        case wxID_OK: {
            saveFileName = saveFileDialog.GetFilename();
            // 세이브 및 적용이 완료했을 경우.
            saveFilePath = saveFileDialog.GetPath();
            break;
        }
        }
    }
 
    // 현재 텍스트 컨트롤의 내용을 파일에 저장합니다.
    if (!m_textControl->SaveFile(saveFilePath)) {
        // 현재 텍스트의 내용을 파일에 저장하지 못한다면.
        wxMessageBox("Could Not save the File!""Error", wxOK);
        return;
    }
 
    m_currentFileName = saveFileName;
    m_currentFilePath = saveFilePath;
 
    wxString titleNames = m_currentFileName;
    titleNames += " - Notepad";
    // 타이틀을 열린 파일의 이름으로 설정합니다.
    SetTitle(titleNames);
}
 
cs

 

 이 후에 Open을 했을 경우에 작동할 이벤트 핸들러를 적용해야한다.

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
31
32
33
34
35
36
37
38
39
40
41
42
43
void MyFrame::OnOpen(wxCommandEvent& event)
{
    wxFileDialog openFileDialog(this, _("Open TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
 
    wxString openFileName = m_currentFileName;
    wxString openFilePath = m_currentFilePath;
 
    switch (openFileDialog.ShowModal()) {
    case wxID_OK: {
        openFileName = openFileDialog.GetFilename();
        // 세이브 및 적용이 완료했을 경우.
        openFilePath = openFileDialog.GetPath();
        break;
    }
    case wxID_CANCEL: {
        return// 사용자가 취소했을 때
    }
    }
 
    std::ifstream file(openFilePath.ToStdString());
    // 파일을 열고 텍스트 컨트롤에 내용을 로드합니다.
    if (m_textControl->LoadFile(openFilePath)) {
        std::stringstream buffer;
        buffer << file.rdbuf(); // 파일의 내용을 buffer에 읽어 들입니다.
        file.close(); // 파일을 닫습니다.
 
        // textControl의 내용을 갱신합니다.
        m_textControl->SetValue(buffer.str());
        //textControl->SetLabelText(buffer.str());
        m_currentFileName = openFileName;
        m_currentFilePath = openFilePath;
        
        wxString titleNames = m_currentFileName;
        titleNames += " - Notepad";
        // 타이틀을 열린 파일의 이름으로 설정합니다.
        SetTitle(titleNames);
 
    }
    else {
        wxMessageBox("Cannot open File!""Error", wxOK | wxICON_ERROR);
    }
}
cs

 

 이렇게 하면, 열었을때, 저장을 바로 적용할 수 있고,

 저장 경로를 정했을 경우에 약간 수정하고 바로 저장을 누르면 적용이 가능해진다.

 

Posted by JunkMam
,

 View라는 메뉴를 추가하여 StatusBar를 On/Off하는 기능을 적용하기 위해서 다음과 같이 한다.

 

 wxMain.h

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#pragma once
#include "wx/wx.h"
#include <wx/filedlg.h>
#include <wx/textctrl.h>
#include <wx/splitter.h>
 
// Font Dialog
#include <wx/fontdlg.h>
 
// 파일을 읽어 들이기 위한 용도.
#include <fstream>
#include <sstream>
 
#include "wxOptionsDialog.h"
 
enum
{
    ID_QUIT,
    ID_WordWarp,
    ID_FontSetting,
    ID_StatusBar,
};
 
enum {
    MY_EVENT_ID = 10001,
};
 
// 메뉴 항목 ID 정의
enum
{
    ID_NEW_WINDOW = wxID_HIGHEST + 1 // 새 창을 위한 고유 ID
};
 
class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};
 
class MyFrame : public wxFrame
{
public:
    MyFrame(const wxString& title);
 
    void OnQuit(wxCommandEvent& event);
 
private:
    wxTextCtrl* m_textControl;
    //wxOptionDialog* m_dialog;
    wxFont* m_font;
 
    wxStatusBar* m_statusBar;
 
    // 메뉴바 및 메뉴 변수.
    wxMenuBar* m_menuBar;
    wxMenu* m_menuFile;
    wxMenu* m_menuFormat;
    wxMenu* m_menuView;
 
    void OnNew(wxCommandEvent& event);
    void OnNewWindow(wxCommandEvent& event);
    void OnOpen(wxCommandEvent& event);
    void OnSave(wxCommandEvent& event);
    void OnButtonClick(wxCommandEvent& event);
 
    // Format 메뉴에 적용할 이벤트 핸들러
    void OnToggleWordWrap(wxCommandEvent& event);
    void OnFontSetting(wxCommandEvent& event);
 
    // View 메뉴에 적용할 이벤트 핸들러
    void OnToggleStatusBar(wxCommandEvent& event);
 
 
    // 이벤트를 받기 위한 메소드
    void OnMyCustomEvent(MyCustomEvent& event);
};
 
cs

 

 여기서 추가 된것은

 m_statusBar이다.

 m_statusBar를 이용해서 상태바를 보이고, 보이지 않게 할 수 있다.

 

 wxMain.cpp

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#include "wxMain.h"
 
wxIMPLEMENT_APP(MyApp);
 
bool MyApp::OnInit()
{
    MyFrame* frame = new MyFrame("No Title - Notepad");
    frame->Show(true);
    return true;
}
 
MyFrame::MyFrame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
    m_menuFile = new wxMenu;
    m_menuFile->Append(wxID_NEW, "&New\tCtrl-N""New a Notepad");
    m_menuFile->Append(ID_NEW_WINDOW, "&New Windows\tCtrl+Shift+N""Open a new window.");
    m_menuFile->Append(wxID_OPEN, "&Open\tCtrl-O""Open a file");
    m_menuFile->Append(wxID_SAVE, "&Save\tCtrl-S""Save the file");
    m_menuFile->AppendSeparator();
    m_menuFile->Append(ID_QUIT, "E&xit\tAlt-X""프로그램 종료");
 
    m_menuFormat = new wxMenu;
    m_menuFormat->AppendCheckItem(ID_WordWarp, "Word &Wrap\tCtrl+W""Toggle word wrapping.");
    m_menuFormat->Append(ID_FontSetting, "&Font""Font Set Menu");
 
    m_menuView = new wxMenu;
    m_menuView->AppendCheckItem(ID_StatusBar, "Show &StatusBar""Toggle Status Bar.");
    
    m_menuBar = new wxMenuBar;
    m_menuBar->Append(m_menuFile, "&File");
    m_menuBar->Append(m_menuFormat, "F&omat");
    m_menuBar->Append(m_menuView, "&View");
 
    SetMenuBar(m_menuBar);
 
    m_textControl = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
 
    // sizer를 생성하여 텍스트 컨트롤의 크기를 조정합니다.
    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(m_textControl, 1, wxEXPAND | wxALL, 0); // wxEXPAND는 컨트롤이 sizer의 가능한 모든 공간을 차지하도록 합니다. 1은 비율을 의미하며, 이 경우 다른 컨트롤이 없으므로 전체 크기를 차지합니다.
 
    // 프레임에 sizer를 설정합니다.
    this->SetSizer(sizer);
    this->Layout(); // sizer를 강제로 다시 계산하여 적용합니다.
 
    // 폰트 설정
    wxFont font(16, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
    m_textControl->SetFont(font);
 
    //m_statusBar = new wxStatusBar(this);
    m_statusBar = CreateStatusBar();
    SetStatusText("Ready");
    // ID_StatusBar 메뉴 항목을 자동으로 체크되어 있도록 설정
    m_menuView->Check(ID_StatusBar, true);
 
    // 이벤트 핸들러 연결
    Bind(wxEVT_MENU, &MyFrame::OnNew, this, wxID_NEW);
 
    // MyFrame 생성자 또는 초기화 함수 내
    Bind(wxEVT_MENU, &MyFrame::OnNewWindow, this, ID_NEW_WINDOW);
 
    Bind(wxEVT_MENU, &MyFrame::OnOpen, this, wxID_OPEN);
    Bind(wxEVT_MENU, &MyFrame::OnSave, this, wxID_SAVE);
 
    Bind(wxEVT_MENU, &MyFrame::OnQuit, this, ID_QUIT);
 
    // 메뉴 Format에 관련된 이벤트 핸들러
    Bind(wxEVT_MENU, &MyFrame::OnToggleWordWrap, this, ID_WordWarp);
    Bind(wxEVT_MENU, &MyFrame::OnFontSetting, this, ID_FontSetting);
 
    // 메뉴 View에 관련된 이벤트 핸들러
    Bind(wxEVT_MENU, &MyFrame::OnToggleStatusBar, this, ID_StatusBar);
 
    // 이벤트 처리기 등록
    Bind(MY_CUSTOM_EVENT, &MyFrame::OnMyCustomEvent, this);
}
 
void MyFrame::OnQuit(wxCommandEvent& event)
{
    Close(true);
}
 
void MyFrame::OnNew(wxCommandEvent& event) {
    // 텍스트 컨트롤의 내용을 비웁니다.
    m_textControl->Clear();
 
    // 타이틀에 메시지를 새로 작성합니다.
    wxString titleNames = "No Title";
    titleNames += " - Notepad";
    SetTitle(titleNames);
 
    // 상태 표시줄에 메시지를 표시합니다.
    SetStatusText("New document created.");
}
 
// MyFrame 클래스 내
void MyFrame::OnNewWindow(wxCommandEvent& event)
{
    // 새로운 창을 생성하고 표시
    MyFrame* newFrame = new MyFrame("No Title - Notepad");
    newFrame->Show(true);
}
 
void MyFrame::OnOpen(wxCommandEvent& event)
{
    wxFileDialog openFileDialog(this, _("Open TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
    if (openFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    std::ifstream file(openFileDialog.GetPath().ToStdString());
    // 파일을 열고 텍스트 컨트롤에 내용을 로드합니다.
    if (m_textControl->LoadFile(openFileDialog.GetPath())) {
        std::stringstream buffer;
        buffer << file.rdbuf(); // 파일의 내용을 buffer에 읽어 들입니다.
        file.close(); // 파일을 닫습니다.
 
        // textControl의 내용을 갱신합니다.
        m_textControl->SetValue(buffer.str());
        //textControl->SetLabelText(buffer.str());
        
        wxString titleNames = openFileDialog.GetFilename();
        titleNames += " - Notepad";
        // 타이틀을 열린 파일의 이름으로 설정합니다.
        SetTitle(titleNames);
 
    }
    else {
        wxMessageBox("Cannot open File!""Error", wxOK | wxICON_ERROR);
    }
}
 
void MyFrame::OnSave(wxCommandEvent& event)
{
    wxFileDialog saveFileDialog(this, _("Save TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
    if (saveFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    // 현재 텍스트 컨트롤의 내용을 파일에 저장합니다.
    m_textControl->SaveFile(saveFileDialog.GetPath());
 
    wxString titleNames = saveFileDialog.GetFilename();
    titleNames += " - Notepad";
    // 타이틀을 열린 파일의 이름으로 설정합니다.
    SetTitle(titleNames);
}
 
void MyFrame::OnToggleWordWrap(wxCommandEvent& event)
{
    bool isChecked = m_menuFormat->IsChecked(ID_WordWarp);
    m_textControl->SetWindowStyleFlag(isChecked ? (m_textControl->GetWindowStyleFlag() | wxTE_WORDWRAP) : (m_textControl->GetWindowStyleFlag() & ~wxTE_WORDWRAP));
    m_textControl->Refresh(); // 화면 갱신
}
 
void MyFrame::OnFontSetting(wxCommandEvent& event)
{
    /*dialog = new wxOptionDialog(this, wxID_ANY, "Settings");
    dialog->ShowModal();*/
 
    wxFontData fontData;
    fontData.SetInitialFont(m_textControl->GetFont());
    fontData.SetColour(m_textControl->GetForegroundColour());
 
    wxFontDialog fontDialog(this, fontData);
    if (fontDialog.ShowModal() == wxID_OK)
    {
        wxFontData retData = fontDialog.GetFontData();
        wxFont font = retData.GetChosenFont();
        wxColour colour = retData.GetColour();
 
        m_textControl->SetFont(font);
        m_textControl->SetForegroundColour(colour);
    }
}
 
void MyFrame::OnToggleStatusBar(wxCommandEvent& event)
{
    bool isChecked = m_menuView->IsChecked(ID_StatusBar);
 
    // StatusBar의 보임/숨김 상태를 설정합니다.
    if (m_statusBar) { // m_statusBar가 유효한지 확인합니다.
        m_statusBar->Show(isChecked);
    }
 
    // 프레임의 레이아웃을 갱신하여 m_textControl이 남은 공간을 가득 채우도록 합니다.
    this->Layout();
 
    // 프레임의 크기를 조정하여 내부 컨트롤들이 적절하게 배치되도록 합니다.
    // 이 부분은 필요에 따라 추가하거나 생략할 수 있습니다.
    this->SendSizeEvent();
}
 
// 이벤트 처리 함수 구현
void MyFrame::OnMyCustomEvent(MyCustomEvent& event)
{
    const wxFont info = event.GetwxFont();
 
    int fontSize = info.GetPointSize();
    // 이벤트와 함께 전달된 정보 처리
    m_textControl->SetFont(info);
 
    //textControl->SetFont(font);
    //m_dialog->Destroy(); // dialog를 안전하게 삭제
    //delete m_dialog;
}
cs

 

 CreateStatusBar()는 wxStatusBar라는 클래스를 반환한다. 그래서, m_statusBar에 저장하면, 컨트롤하기 편해진다.

1
    m_statusBar = CreateStatusBar();
cs

 

View 메뉴에서 StatusBar를 컨트롤하기 위해서 이벤트 핸들러를 적용한다.

1
2
3
 
    // 메뉴 View에 관련된 이벤트 핸들러
    Bind(wxEVT_MENU, &MyFrame::OnToggleStatusBar, this, ID_StatusBar);
cs

 

 메뉴 이벤트 핸들러 및 Check을 컨트롤하기 위해서

 ID_StatusBar라는 열거형을 작성해줘야한다.

1
2
3
4
5
6
7
8
9
 
enum
{
    ID_QUIT,
    ID_WordWarp,
    ID_FontSetting,
    ID_StatusBar,
};
 
cs

 

이제, 이벤트 핸들러인 OnToggleStatusBar을 구현한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
void MyFrame::OnToggleStatusBar(wxCommandEvent& event)
{
    bool isChecked = m_menuView->IsChecked(ID_StatusBar);
 
    // StatusBar의 보임/숨김 상태를 설정합니다.
    if (m_statusBar) { // m_statusBar가 유효한지 확인합니다.
        m_statusBar->Show(isChecked);
    }
 
    // 프레임의 레이아웃을 갱신하여 m_textControl이 남은 공간을 가득 채우도록 합니다.
    this->Layout();
 
    // 프레임의 크기를 조정하여 내부 컨트롤들이 적절하게 배치되도록 합니다.
    // 이 부분은 필요에 따라 추가하거나 생략할 수 있습니다.
    this->SendSizeEvent();
}
 
cs

 

 이렇게 하면, StatusBar가 보여지는거와 보이지 않는 것에 따라서 TextCtrl의 크기를 재정의 하여 비어지는 경우가 없어진다.

 

 여기서 CheckItem들은 기본이 Checked가 false인 상태이다.

 그래서 강제로 Checked true로 설정해준다면, 'm_menuView->Check(ID_StatusBar, true);'을 추가해주면 된다.

 

Posted by JunkMam
,

 wxMain에서 새 창을 만들면서 새 창을 띄우는 방식으로 개별로 윈도우를 만들어서 작업 할 수 있는 기능이다.

 

 wxMain.h

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#pragma once
#include "wx/wx.h"
#include <wx/filedlg.h>
#include <wx/textctrl.h>
#include <wx/splitter.h>
 
// Font Dialog
#include <wx/fontdlg.h>
 
// 파일을 읽어 들이기 위한 용도.
#include <fstream>
#include <sstream>
 
#include "wxOptionsDialog.h"
 
enum
{
    ID_QUIT,
    ID_WORD_WRAP,
    ID_FontSetting,
};
 
enum {
    MY_EVENT_ID = 10001,
};
 
// 메뉴 항목 ID 정의
enum
{
    ID_NEW_WINDOW = wxID_HIGHEST + 1 // 새 창을 위한 고유 ID
};
 
class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};
 
class MyFrame : public wxFrame
{
public:
    MyFrame(const wxString& title);
 
    void OnQuit(wxCommandEvent& event);
 
private:
    wxTextCtrl* textControl;
    wxOptionDialog* dialog;
    wxFont* font;
 
    // 메뉴바 및 메뉴 변수.
    wxMenuBar* menuBar;
    wxMenu* menuFile;
    wxMenu* menuFormat;
 
    void OnNew(wxCommandEvent& event);
    void OnNewWindow(wxCommandEvent& event);
    void OnOpen(wxCommandEvent& event);
    void OnSave(wxCommandEvent& event);
    void OnButtonClick(wxCommandEvent& event);
 
    // 세팅 창을 띄우기 위한 메소드
    void OnToggleWordWrap(wxCommandEvent& event);
    void OnFontSetting(wxCommandEvent& event);
 
    // 이벤트를 받기 위한 메소드
    void OnMyCustomEvent(MyCustomEvent& event);
};
 
cs

 

 wxMain.cpp

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include "wxMain.h"
 
wxIMPLEMENT_APP(MyApp);
 
bool MyApp::OnInit()
{
    MyFrame* frame = new MyFrame("No Title - Notepad");
    frame->Show(true);
    return true;
}
 
MyFrame::MyFrame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
    menuFile = new wxMenu;
    menuFile->Append(wxID_NEW, "&New\tCtrl-N""New a Notepad");
    menuFile->Append(ID_NEW_WINDOW, "&New Windows\tCtrl+Shift+N""Open a new window.");
    menuFile->Append(wxID_OPEN, "&Open\tCtrl-O""Open a file");
    menuFile->Append(wxID_SAVE, "&Save\tCtrl-S""Save the file");
    menuFile->AppendSeparator();
    menuFile->Append(ID_QUIT, "E&xit\tAlt-X""프로그램 종료");
 
    menuFormat = new wxMenu;
    menuFormat->AppendCheckItem(ID_WORD_WRAP, "Word &Wrap\tCtrl+W""Toggle word wrapping.");
    menuFormat->Append(ID_FontSetting, "&Font""Font Set Menu");
    
 
    menuBar = new wxMenuBar;
    menuBar->Append(menuFile, "&File");
    menuBar->Append(menuFormat, "&F&omat");
 
    SetMenuBar(menuBar);
 
    textControl = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
 
    // sizer를 생성하여 텍스트 컨트롤의 크기를 조정합니다.
    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(textControl, 1, wxEXPAND | wxALL, 0); // wxEXPAND는 컨트롤이 sizer의 가능한 모든 공간을 차지하도록 합니다. 1은 비율을 의미하며, 이 경우 다른 컨트롤이 없으므로 전체 크기를 차지합니다.
 
    // 프레임에 sizer를 설정합니다.
    this->SetSizer(sizer);
    this->Layout(); // sizer를 강제로 다시 계산하여 적용합니다.
 
    // 폰트 설정
    wxFont font(16, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
    textControl->SetFont(font);
 
    CreateStatusBar();
    SetStatusText("Ready");
 
    // 이벤트 핸들러 연결
    Bind(wxEVT_MENU, &MyFrame::OnNew, this, wxID_NEW);
 
    // MyFrame 생성자 또는 초기화 함수 내
    Bind(wxEVT_MENU, &MyFrame::OnNewWindow, this, ID_NEW_WINDOW);
 
    Bind(wxEVT_MENU, &MyFrame::OnOpen, this, wxID_OPEN);
    Bind(wxEVT_MENU, &MyFrame::OnSave, this, wxID_SAVE);
 
    Bind(wxEVT_MENU, &MyFrame::OnQuit, this, ID_QUIT);
 
    // 메뉴 Format에 관련된 이벤트 핸들러
    Bind(wxEVT_MENU, &MyFrame::OnToggleWordWrap, this, ID_WORD_WRAP);
    Bind(wxEVT_MENU, &MyFrame::OnFontSetting, this, ID_FontSetting);
 
    // 이벤트 처리기 등록
    Bind(MY_CUSTOM_EVENT, &MyFrame::OnMyCustomEvent, this);
}
 
void MyFrame::OnQuit(wxCommandEvent& event)
{
    Close(true);
}
 
void MyFrame::OnNew(wxCommandEvent& event) {
    // 텍스트 컨트롤의 내용을 비웁니다.
    textControl->Clear();
 
    // 타이틀에 메시지를 새로 작성합니다.
    wxString titleNames = "No Title";
    titleNames += " - Notepad";
    SetTitle(titleNames);
 
    // 상태 표시줄에 메시지를 표시합니다.
    SetStatusText("New document created.");
}
 
// MyFrame 클래스 내
void MyFrame::OnNewWindow(wxCommandEvent& event)
{
    // 새로운 창을 생성하고 표시
    MyFrame* newFrame = new MyFrame("No Title - Notepad");
    newFrame->Show(true);
}
 
void MyFrame::OnOpen(wxCommandEvent& event)
{
    wxFileDialog openFileDialog(this, _("Open TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
    if (openFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    std::ifstream file(openFileDialog.GetPath().ToStdString());
    // 파일을 열고 텍스트 컨트롤에 내용을 로드합니다.
    if (textControl->LoadFile(openFileDialog.GetPath())) {
        std::stringstream buffer;
        buffer << file.rdbuf(); // 파일의 내용을 buffer에 읽어 들입니다.
        file.close(); // 파일을 닫습니다.
 
        // textControl의 내용을 갱신합니다.
        textControl->SetValue(buffer.str());
        //textControl->SetLabelText(buffer.str());
        
        wxString titleNames = openFileDialog.GetFilename();
        titleNames += " - Notepad";
        // 타이틀을 열린 파일의 이름으로 설정합니다.
        SetTitle(titleNames);
 
    }
    else {
        wxMessageBox("Cannot open File!""Error", wxOK | wxICON_ERROR);
    }
}
 
void MyFrame::OnSave(wxCommandEvent& event)
{
    wxFileDialog saveFileDialog(this, _("Save TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
    if (saveFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    // 현재 텍스트 컨트롤의 내용을 파일에 저장합니다.
    textControl->SaveFile(saveFileDialog.GetPath());
 
    wxString titleNames = saveFileDialog.GetFilename();
    titleNames += " - Notepad";
    // 타이틀을 열린 파일의 이름으로 설정합니다.
    SetTitle(titleNames);
}
 
void MyFrame::OnToggleWordWrap(wxCommandEvent& event)
{
    bool isChecked = menuFormat->IsChecked(ID_WORD_WRAP);
    textControl->SetWindowStyleFlag(isChecked ? (textControl->GetWindowStyleFlag() | wxTE_WORDWRAP) : (textControl->GetWindowStyleFlag() & ~wxTE_WORDWRAP));
    textControl->Refresh(); // 화면 갱신
}
 
void MyFrame::OnFontSetting(wxCommandEvent& event)
{
    /*dialog = new wxOptionDialog(this, wxID_ANY, "Settings");
    dialog->ShowModal();*/
 
    wxFontData fontData;
    fontData.SetInitialFont(textControl->GetFont());
    fontData.SetColour(textControl->GetForegroundColour());
 
    wxFontDialog fontDialog(this, fontData);
    if (fontDialog.ShowModal() == wxID_OK)
    {
        wxFontData retData = fontDialog.GetFontData();
        wxFont font = retData.GetChosenFont();
        wxColour colour = retData.GetColour();
 
        textControl->SetFont(font);
        textControl->SetForegroundColour(colour);
    }
}
 
// 이벤트 처리 함수 구현
void MyFrame::OnMyCustomEvent(MyCustomEvent& event)
{
    const wxFont info = event.GetwxFont();
 
    int fontSize = info.GetPointSize();
    // 이벤트와 함께 전달된 정보 처리
    textControl->SetFont(info);
 
    //textControl->SetFont(font);
    dialog->Destroy(); // dialog를 안전하게 삭제
    delete dialog;
}
cs

 

 이렇게 하면, Ctrl+Shift+N을 눌을때마다 새 창을 띄우는게 가능해진다.

Posted by JunkMam
,

 notepad을 따라한다고 했을때, notepad을 구현하는 방법은 다음과 같이 한다.

 wxWidgets.h

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#pragma once
#include "wx/wx.h"
#include <wx/filedlg.h>
#include <wx/textctrl.h>
#include <wx/splitter.h>
 
// Font Dialog
#include <wx/fontdlg.h>
 
// 파일을 읽어 들이기 위한 용도.
#include <fstream>
#include <sstream>
 
#include "wxOptionsDialog.h"
 
enum
{
    ID_QUIT,
    ID_WORD_WRAP,
    ID_FontSetting,
};
 
enum {
    MY_EVENT_ID = 10001,
};
 
// ID 값 정의
enum
{
    ID_Settings_Menu = wxID_HIGHEST + 1 // 사용자 정의 ID
};
 
class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};
 
class MyFrame : public wxFrame
{
public:
    MyFrame(const wxString& title);
 
    void OnQuit(wxCommandEvent& event);
 
private:
    wxTextCtrl* textControl;
    wxOptionDialog* dialog;
    wxFont* font;
 
    // 메뉴바 및 메뉴 변수.
    wxMenuBar* menuBar;
    wxMenu* menuFile;
    wxMenu* menuFormat;
 
    void OnNew(wxCommandEvent& event);
    void OnOpen(wxCommandEvent& event);
    void OnSave(wxCommandEvent& event);
    void OnButtonClick(wxCommandEvent& event);
 
    // 세팅 창을 띄우기 위한 메소드
    void OnToggleWordWrap(wxCommandEvent& event);
    void OnFontSetting(wxCommandEvent& event);
 
    // 이벤트를 받기 위한 메소드
    void OnMyCustomEvent(MyCustomEvent& event);
};
 
cs

 

wxMain.cpp

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include "wxMain.h"
 
wxIMPLEMENT_APP(MyApp);
 
bool MyApp::OnInit()
{
    MyFrame* frame = new MyFrame("No Title - Notepad");
    frame->Show(true);
    return true;
}
 
MyFrame::MyFrame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
    menuFile = new wxMenu;
    menuFile->Append(wxID_NEW, "&New\tCtrl-N""New a Notepad");
    menuFile->Append(wxID_OPEN, "&Open\tCtrl-O""Open a file");
    menuFile->Append(wxID_SAVE, "&Save\tCtrl-S""Save the file");
    menuFile->AppendSeparator();
    menuFile->Append(ID_QUIT, "E&xit\tAlt-X""프로그램 종료");
 
    menuFormat = new wxMenu;
    menuFormat->AppendCheckItem(ID_WORD_WRAP, "Word &Wrap\tCtrl+W""Toggle word wrapping.");
    menuFormat->Append(ID_FontSetting, "&Font""Font Set Menu");
    
 
    menuBar = new wxMenuBar;
    menuBar->Append(menuFile, "&File");
    menuBar->Append(menuFormat, "&F&omat");
 
    SetMenuBar(menuBar);
 
    textControl = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
 
    // sizer를 생성하여 텍스트 컨트롤의 크기를 조정합니다.
    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(textControl, 1, wxEXPAND | wxALL, 0); // wxEXPAND는 컨트롤이 sizer의 가능한 모든 공간을 차지하도록 합니다. 1은 비율을 의미하며, 이 경우 다른 컨트롤이 없으므로 전체 크기를 차지합니다.
 
    // 프레임에 sizer를 설정합니다.
    this->SetSizer(sizer);
    this->Layout(); // sizer를 강제로 다시 계산하여 적용합니다.
 
    // 폰트 설정
    wxFont font(16, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
    textControl->SetFont(font);
 
    CreateStatusBar();
    SetStatusText("Ready");
 
    // 이벤트 핸들러 연결
    Bind(wxEVT_MENU, &MyFrame::OnNew, this, wxID_NEW);
    Bind(wxEVT_MENU, &MyFrame::OnOpen, this, wxID_OPEN);
    Bind(wxEVT_MENU, &MyFrame::OnSave, this, wxID_SAVE);
 
    Bind(wxEVT_MENU, &MyFrame::OnQuit, this, ID_QUIT);
 
    // 메뉴 Format에 관련된 이벤트 핸들러
    Bind(wxEVT_MENU, &MyFrame::OnToggleWordWrap, this, ID_WORD_WRAP);
    Bind(wxEVT_MENU, &MyFrame::OnFontSetting, this, ID_FontSetting);
 
    // 이벤트 처리기 등록
    Bind(MY_CUSTOM_EVENT, &MyFrame::OnMyCustomEvent, this);
}
 
void MyFrame::OnQuit(wxCommandEvent& event)
{
    Close(true);
}
 
void MyFrame::OnNew(wxCommandEvent& event) {
    // 텍스트 컨트롤의 내용을 비웁니다.
    textControl->Clear();
 
    // 타이틀에 메시지를 새로 작성합니다.
    wxString titleNames = "No Title";
    titleNames += " - Notepad";
    SetTitle(titleNames);
 
    // 상태 표시줄에 메시지를 표시합니다.
    SetStatusText("New document created.");
}
 
void MyFrame::OnOpen(wxCommandEvent& event)
{
    wxFileDialog openFileDialog(this, _("Open TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
    if (openFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    std::ifstream file(openFileDialog.GetPath().ToStdString());
    // 파일을 열고 텍스트 컨트롤에 내용을 로드합니다.
    if (textControl->LoadFile(openFileDialog.GetPath())) {
        std::stringstream buffer;
        buffer << file.rdbuf(); // 파일의 내용을 buffer에 읽어 들입니다.
        file.close(); // 파일을 닫습니다.
 
        // textControl의 내용을 갱신합니다.
        textControl->SetValue(buffer.str());
        //textControl->SetLabelText(buffer.str());
        
        wxString titleNames = openFileDialog.GetFilename();
        titleNames += " - Notepad";
        // 타이틀을 열린 파일의 이름으로 설정합니다.
        SetTitle(titleNames);
 
    }
    else {
        wxMessageBox("Cannot open File!""Error", wxOK | wxICON_ERROR);
    }
}
 
void MyFrame::OnSave(wxCommandEvent& event)
{
    wxFileDialog saveFileDialog(this, _("Save TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
    if (saveFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    // 현재 텍스트 컨트롤의 내용을 파일에 저장합니다.
    textControl->SaveFile(saveFileDialog.GetPath());
 
    wxString titleNames = saveFileDialog.GetFilename();
    titleNames += " - Notepad";
    // 타이틀을 열린 파일의 이름으로 설정합니다.
    SetTitle(titleNames);
}
 
void MyFrame::OnToggleWordWrap(wxCommandEvent& event)
{
    bool isChecked = menuFormat->IsChecked(ID_WORD_WRAP);
    textControl->SetWindowStyleFlag(isChecked ? (textControl->GetWindowStyleFlag() | wxTE_WORDWRAP) : (textControl->GetWindowStyleFlag() & ~wxTE_WORDWRAP));
    textControl->Refresh(); // 화면 갱신
}
 
void MyFrame::OnFontSetting(wxCommandEvent& event)
{
    /*dialog = new wxOptionDialog(this, wxID_ANY, "Settings");
    dialog->ShowModal();*/
 
    wxFontData fontData;
    fontData.SetInitialFont(textControl->GetFont());
    fontData.SetColour(textControl->GetForegroundColour());
 
    wxFontDialog fontDialog(this, fontData);
    if (fontDialog.ShowModal() == wxID_OK)
    {
        wxFontData retData = fontDialog.GetFontData();
        wxFont font = retData.GetChosenFont();
        wxColour colour = retData.GetColour();
 
        textControl->SetFont(font);
        textControl->SetForegroundColour(colour);
    }
}
 
// 이벤트 처리 함수 구현
void MyFrame::OnMyCustomEvent(MyCustomEvent& event)
{
    const wxFont info = event.GetwxFont();
 
    int fontSize = info.GetPointSize();
    // 이벤트와 함께 전달된 정보 처리
    textControl->SetFont(info);
 
    //textControl->SetFont(font);
    dialog->Destroy(); // dialog를 안전하게 삭제
    delete dialog;
}
cs

 

 이렇게 하면, New을 클릭했을 경우에 Notepad의 값을 Clear되면서 초기화 할 수 있게 된다.

 

 

Posted by JunkMam
,

 wxWidgets에서 설정한 상태를 확인하거나 적용해서 출력하는 부분을 구현하고자 한다.

 

 다음과 같은 방식을 wxWidgets에선 다음과 같은 메소드를 제공한다.

1
2
menuOptions->AppendCheckItem(ID_WORD_WRAP, "Word &Wrap\tCtrl+W""Toggle word wrapping.");
 
cs

 

 그리고, 이걸 토글해주는 이벤트 핸들러를 적용해야된다.

1
2
3
4
5
6
void MyFrame::OnToggleWordWrap(wxCommandEvent& event)
{
    bool isChecked = menuOptions->IsChecked(ID_WORD_WRAP);
    textControl->SetWindowStyleFlag(isChecked ? (textControl->GetWindowStyleFlag() | wxTE_WORDWRAP) : (textControl->GetWindowStyleFlag() & ~wxTE_WORDWRAP));
    textControl->Refresh(); // 화면 갱신
}
cs

 

 그리고, 이 핸들러를 연결하기 위해서 Bind를 이용해서 연결해준다.

1
2
Bind(wxEVT_MENU, &MyFrame::OnToggleWordWrap, this, ID_WORD_WRAP);
 
cs

 

 전체적으로 적용하면,

 wxMain.cpp와 wxMain.h에 다음과 같이 적용한다.

 

wxMain.h

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#pragma once
#include "wx/wx.h"
#include <wx/filedlg.h>
#include <wx/textctrl.h>
#include <wx/splitter.h>
 
// Font Dialog
#include <wx/fontdlg.h>
 
// 파일을 읽어 들이기 위한 용도.
#include <fstream>
#include <sstream>
 
#include "wxOptionsDialog.h"
 
enum
{
    ID_QUIT,
    ID_WORD_WRAP,
    ID_FontSetting,
};
 
enum {
    MY_EVENT_ID = 10001,
};
 
// ID 값 정의
enum
{
    ID_Settings_Menu = wxID_HIGHEST + 1 // 사용자 정의 ID
};
 
class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};
 
class MyFrame : public wxFrame
{
public:
    MyFrame(const wxString& title);
 
    void OnQuit(wxCommandEvent& event);
 
private:
    wxTextCtrl* textControl;
    wxOptionDialog* dialog;
    wxFont* font;
 
    // 메뉴바 및 메뉴 변수.
    wxMenuBar* menuBar;
    wxMenu* menuFile;
    wxMenu* menuFormat;
 
    void OnOpen(wxCommandEvent& event);
    void OnSave(wxCommandEvent& event);
    void OnButtonClick(wxCommandEvent& event);
 
    // 세팅 창을 띄우기 위한 메소드
    void OnToggleWordWrap(wxCommandEvent& event);
    void OnFontSetting(wxCommandEvent& event);
 
    // 이벤트를 받기 위한 메소드
    void OnMyCustomEvent(MyCustomEvent& event);
};
 
cs

 

wxMain.cpp

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include "wxMain.h"
 
wxIMPLEMENT_APP(MyApp);
 
bool MyApp::OnInit()
{
    MyFrame* frame = new MyFrame("Serial Graph");
    frame->Show(true);
    return true;
}
 
MyFrame::MyFrame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
    menuFile = new wxMenu;
    menuFile->Append(wxID_OPEN, "&Open\tCtrl-O""Open a file");
    menuFile->Append(wxID_SAVE, "&Save\tCtrl-S""Save the file");
    menuFile->AppendSeparator();
    menuFile->Append(ID_QUIT, "E&xit\tAlt-X""프로그램 종료");
 
    menuFormat = new wxMenu;
    menuFormat->AppendCheckItem(ID_WORD_WRAP, "Word &Wrap\tCtrl+W""Toggle word wrapping.");
    menuFormat->Append(ID_FontSetting, "&Font""Font Set Menu");
    
 
    menuBar = new wxMenuBar;
    menuBar->Append(menuFile, "&File");
    menuBar->Append(menuFormat, "&F&omat");
 
    SetMenuBar(menuBar);
 
    textControl = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
 
    // sizer를 생성하여 텍스트 컨트롤의 크기를 조정합니다.
    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(textControl, 1, wxEXPAND | wxALL, 0); // wxEXPAND는 컨트롤이 sizer의 가능한 모든 공간을 차지하도록 합니다. 1은 비율을 의미하며, 이 경우 다른 컨트롤이 없으므로 전체 크기를 차지합니다.
 
    // 프레임에 sizer를 설정합니다.
    this->SetSizer(sizer);
    this->Layout(); // sizer를 강제로 다시 계산하여 적용합니다.
 
    // 폰트 설정
    wxFont font(16, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
    textControl->SetFont(font);
 
    CreateStatusBar();
    SetStatusText("Ready");
 
    // 이벤트 핸들러 연결
    Bind(wxEVT_MENU, &MyFrame::OnQuit, this, ID_QUIT);
    Bind(wxEVT_MENU, &MyFrame::OnOpen, this, wxID_OPEN);
    Bind(wxEVT_MENU, &MyFrame::OnSave, this, wxID_SAVE);
 
    // 메뉴 Format에 관련된 이벤트 핸들러
    Bind(wxEVT_MENU, &MyFrame::OnToggleWordWrap, this, ID_WORD_WRAP);
    Bind(wxEVT_MENU, &MyFrame::OnFontSetting, this, ID_FontSetting);
 
    // 이벤트 처리기 등록
    Bind(MY_CUSTOM_EVENT, &MyFrame::OnMyCustomEvent, this);
}
 
void MyFrame::OnQuit(wxCommandEvent& event)
{
    Close(true);
}
 
void MyFrame::OnOpen(wxCommandEvent& event)
{
    wxFileDialog openFileDialog(this, _("Open TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
    if (openFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    std::ifstream file(openFileDialog.GetPath().ToStdString());
    // 파일을 열고 텍스트 컨트롤에 내용을 로드합니다.
    if (textControl->LoadFile(openFileDialog.GetPath())) {
        std::stringstream buffer;
        buffer << file.rdbuf(); // 파일의 내용을 buffer에 읽어 들입니다.
        file.close(); // 파일을 닫습니다.
 
        // textControl의 내용을 갱신합니다.
        textControl->SetValue(buffer.str());
        //textControl->SetLabelText(buffer.str());
        // 타이틀을 열린 파일의 이름으로 설정합니다.
        SetTitle(openFileDialog.GetFilename());
 
    }
    else {
        wxMessageBox("Cannot open File!""Error", wxOK | wxICON_ERROR);
    }
}
 
void MyFrame::OnSave(wxCommandEvent& event)
{
    wxFileDialog saveFileDialog(this, _("Save TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
    if (saveFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    // 현재 텍스트 컨트롤의 내용을 파일에 저장합니다.
    textControl->SaveFile(saveFileDialog.GetPath());
}
 
void MyFrame::OnToggleWordWrap(wxCommandEvent& event)
{
    bool isChecked = menuFormat->IsChecked(ID_WORD_WRAP);
    textControl->SetWindowStyleFlag(isChecked ? (textControl->GetWindowStyleFlag() | wxTE_WORDWRAP) : (textControl->GetWindowStyleFlag() & ~wxTE_WORDWRAP));
    textControl->Refresh(); // 화면 갱신
}
 
void MyFrame::OnFontSetting(wxCommandEvent& event)
{
    /*dialog = new wxOptionDialog(this, wxID_ANY, "Settings");
    dialog->ShowModal();*/
 
    wxFontData fontData;
    fontData.SetInitialFont(textControl->GetFont());
    fontData.SetColour(textControl->GetForegroundColour());
 
    wxFontDialog fontDialog(this, fontData);
    if (fontDialog.ShowModal() == wxID_OK)
    {
        wxFontData retData = fontDialog.GetFontData();
        wxFont font = retData.GetChosenFont();
        wxColour colour = retData.GetColour();
 
        textControl->SetFont(font);
        textControl->SetForegroundColour(colour);
    }
 
    //if (dialog.ShowModal() == wxID_OK)
    //{
    //    // 사용자가 설정을 변경하고 OK를 클릭했을 때의 처리
    //    SetStatusText("Settings Updated");
    //}
}
 
// 이벤트 처리 함수 구현
void MyFrame::OnMyCustomEvent(MyCustomEvent& event)
{
    const wxFont info = event.GetwxFont();
 
    int fontSize = info.GetPointSize();
    // 이벤트와 함께 전달된 정보 처리
    textControl->SetFont(info);
 
    //textControl->SetFont(font);
    dialog->Destroy(); // dialog를 안전하게 삭제
    delete dialog;
}
cs

 

 

 적용하면, 다음과 같은 창이 완성된다.

 

 

 

Posted by JunkMam
,

 wxWIdgets에서 Font 설정을 보낸 후에 받는 곳에선 다음과 같이 처리하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
// 이벤트 처리 함수 구현
void MyFrame::OnMyCustomEvent(MyCustomEvent& event)
{
    wxFont info = event.GetwxFont();
    // 이벤트와 함께 전달된 정보 처리
    //textControl->SetFont(info);
 
    wxFont font(info.GetPointSize(), info.GetFamily(), info.GetStyle(), info.GetWeight());
    textControl->SetFont(font);
    //dialog->Destroy(); // dialog를 안전하게 삭제
    //delete dialog;
}
 
cs

 

 이렇게 폰트에 데이터를 전환하여 처리할 수 있다.

 

 wxMain.cpp

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "wxMain.h"
 
wxIMPLEMENT_APP(MyApp);
 
bool MyApp::OnInit()
{
    MyFrame* frame = new MyFrame("Serial Graph");
    frame->Show(true);
    return true;
}
 
MyFrame::MyFrame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
    wxMenu* menuFile = new wxMenu;
    menuFile->Append(wxID_OPEN, "&Open\tCtrl-O""Open a file");
    menuFile->Append(wxID_SAVE, "&Save\tCtrl-S""Save the file");
    menuFile->AppendSeparator();
    menuFile->Append(ID_QUIT, "E&xit\tAlt-X""프로그램 종료");
 
    wxMenu* menuOptions = new wxMenu;
    menuOptions->Append(ID_FontStyle, "Font&Style""Font Style Set Menu");
 
    wxMenuBar* menuBar = new wxMenuBar;
    menuBar->Append(menuFile, "&File");
    menuBar->Append(menuOptions, "&F&omat");
 
    SetMenuBar(menuBar);
 
    textControl = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
 
    // sizer를 생성하여 텍스트 컨트롤의 크기를 조정합니다.
    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(textControl, 1, wxEXPAND | wxALL, 0); // wxEXPAND는 컨트롤이 sizer의 가능한 모든 공간을 차지하도록 합니다. 1은 비율을 의미하며, 이 경우 다른 컨트롤이 없으므로 전체 크기를 차지합니다.
 
    // 프레임에 sizer를 설정합니다.
    this->SetSizer(sizer);
    this->Layout(); // sizer를 강제로 다시 계산하여 적용합니다.
 
    // 폰트 설정
    wxFont font(16, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
    textControl->SetFont(font);
 
    CreateStatusBar();
    SetStatusText("Ready");
 
    // 이벤트 핸들러 연결
    Bind(wxEVT_MENU, &MyFrame::OnQuit, this, ID_QUIT);
    Bind(wxEVT_MENU, &MyFrame::OnOpen, this, wxID_OPEN);
    Bind(wxEVT_MENU, &MyFrame::OnSave, this, wxID_SAVE);
 
    Bind(wxEVT_MENU, &MyFrame::OnSettings, this, ID_FontStyle);
 
    // 이벤트 처리기 등록
    Bind(MY_CUSTOM_EVENT, &MyFrame::OnMyCustomEvent, this);
}
 
void MyFrame::OnQuit(wxCommandEvent& event)
{
    Close(true);
}
 
void MyFrame::OnOpen(wxCommandEvent& event)
{
    wxFileDialog openFileDialog(this, _("Open TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
    if (openFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    std::ifstream file(openFileDialog.GetPath().ToStdString());
    // 파일을 열고 텍스트 컨트롤에 내용을 로드합니다.
    if (textControl->LoadFile(openFileDialog.GetPath())) {
        std::stringstream buffer;
        buffer << file.rdbuf(); // 파일의 내용을 buffer에 읽어 들입니다.
        file.close(); // 파일을 닫습니다.
 
        // textControl의 내용을 갱신합니다.
        textControl->SetValue(buffer.str());
        //textControl->SetLabelText(buffer.str());
        // 타이틀을 열린 파일의 이름으로 설정합니다.
        SetTitle(openFileDialog.GetFilename());
 
    }
    else {
        wxMessageBox("Cannot open File!""Error", wxOK | wxICON_ERROR);
    }
}
 
void MyFrame::OnSave(wxCommandEvent& event)
{
    wxFileDialog saveFileDialog(this, _("Save TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
    if (saveFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    // 현재 텍스트 컨트롤의 내용을 파일에 저장합니다.
    textControl->SaveFile(saveFileDialog.GetPath());
}
 
void MyFrame::OnSettings(wxCommandEvent& event)
{
    dialog = new wxOptionDialog(this, wxID_ANY, "Settings");
    dialog->ShowModal();
 
    //if (dialog.ShowModal() == wxID_OK)
    //{
    //    // 사용자가 설정을 변경하고 OK를 클릭했을 때의 처리
    //    SetStatusText("Settings Updated");
    //}
}
 
// 이벤트 처리 함수 구현
void MyFrame::OnMyCustomEvent(MyCustomEvent& event)
{
    wxFont info = event.GetwxFont();
 
    int fontSize = info.GetPointSize();
    // 이벤트와 함께 전달된 정보 처리
    textControl->SetFont(info);
 
    //textControl->SetFont(font);
    dialog->Destroy(); // dialog를 안전하게 삭제
    delete dialog;
}
cs

 

 

 

 

 

 

 

Posted by JunkMam
,

 폰트 처리하기 위한 창으로 변경해본다.

 

 wxOptionsDialog.h

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
31
32
33
34
35
36
37
38
39
40
41
42
#pragma once
 
#include <wx/wx.h>
#include <wx/combobox.h>
#include <wx/fontenum.h>
 
#include <wx/sizer.h>
 
#include "wxMyCustomEvent.h"
 
#ifndef __WX_WIDGETS_OPTION_DIALOG_H__
#define __WX_WIDGETS_OPTION_DIALOG_H__
 
// ID 값 정의
enum
{
    ID_Options = wxID_HIGHEST + 1 // 사용자 정의 ID
};
 
class wxOptionDialog : public wxDialog
{
public:
    wxOptionDialog(wxWindow* parent, wxWindowID id, const wxString& title,
        const wxPoint& pos = wxDefaultPosition,
        const wxSize& size = wxDefaultSize,
        long style = wxDEFAULT_DIALOG_STYLE);
 
private:
    void OnOkButtonClicked(wxCommandEvent& evnt);
 
    void OnFontChange(wxCommandEvent& evnt);
    void UpdatePreview();
 
 
    wxComboBox* familyComboBox;
    wxComboBox* styleComboBox;
    wxComboBox* sizeComboBox;
 
    wxTextCtrl* previewTextCtrl;
};
 
#endif
cs

 

 wxOptionsDialog.cpp

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
 
#include <wx/wx.h>
 
#include "wxOptionsDialog.h"
 
wxOptionDialog::wxOptionDialog(wxWindow* parent, wxWindowID id, const wxString& title,
    const wxPoint& pos,
    const wxSize& size,
    long style)
    : wxDialog(parent, id, title, pos, size, style) {
 
    // 컨트롤을 담을 메인 사이저 생성
    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
 
    // 설정 대화 상자의 내용을 여기에 구성
    // 폰트 패밀리 선택 콤보박스
    wxArrayString fontFamilies = wxFontEnumerator::GetFacenames();
    familyComboBox = new wxComboBox(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, fontFamilies, wxCB_READONLY);
    mainSizer->Add(new wxStaticText(this, wxID_ANY, wxT("폰트(E):")), 0, wxLEFT | wxTOP, 5);
    mainSizer->Add(familyComboBox, 0, wxLEFT | wxEXPAND, 5);
 
    // 폰트 스타일 선택 콤보박스
    wxArrayString fontStyles;
    fontStyles.Add("보통");
    fontStyles.Add("기울임꼴");
    fontStyles.Add("두껍게");
    styleComboBox = new wxComboBox(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, fontStyles, wxCB_READONLY);
    mainSizer->Add(new wxStaticText(this, wxID_ANY, wxT("폰트 스타일(Y):")), 0, wxLEFT | wxTOP, 5);
    mainSizer->Add(styleComboBox, 0, wxLEFT | wxEXPAND, 5);
 
    // 폰트 크기 선택 콤보박스
    wxArrayString fontSizes;
    for (int i = 8; i < 30++i)
        fontSizes.Add(wxString::Format(wxT("%d"), i));
    sizeComboBox = new wxComboBox(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, fontSizes, wxCB_READONLY);
    mainSizer->Add(new wxStaticText(this, wxID_ANY, wxT("크기(S):")), 0, wxLEFT | wxTOP, 5);
    mainSizer->Add(sizeComboBox, 0, wxLEFT | wxEXPAND, 5);
 
    // 폰트 미리보기
    previewTextCtrl = new wxTextCtrl(this, wxID_ANY, wxT("AaBbYyZz"), wxDefaultPosition, wxDefaultSize, wxTE_CENTER);
    mainSizer->Add(new wxStaticText(this, wxID_ANY, wxT("보기")), 0, wxLEFT | wxTOP, 5);
    mainSizer->Add(previewTextCtrl, 1, wxLEFT | wxEXPAND, 5);
 
    // OK 및 Cancel 버튼 추가
    wxSizer* buttonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
    mainSizer->Add(buttonSizer, 0, wxALL | wxCENTER, 10);
 
    // 메인 사이저를 대화 상자에 설정
    SetSizer(mainSizer);
    mainSizer->SetSizeHints(this); // 이 호출은 대화 상자가 최소 크기로 축소되지 않도록 합니다.
 
    // 이벤트 처리기 등록
    Bind(wxEVT_BUTTON, &wxOptionDialog::OnOkButtonClicked, this, wxID_OK);
 
    // 이벤트 처리기 등록
    Bind(wxEVT_COMBOBOX, &wxOptionDialog::OnFontChange, this, wxID_ANY);
}
 
void wxOptionDialog::OnFontChange(wxCommandEvent& event)
{
    UpdatePreview();
}
 
void wxOptionDialog::UpdatePreview()
{
    wxString family = familyComboBox->GetValue();
    wxString styleName = styleComboBox->GetValue();
    wxString sizeStr = sizeComboBox->GetValue();
    long size;
    if (!sizeStr.ToLong(&size)) return// 크기 변환 실패 시 리턴
 
    wxFont font(wxFontInfo(size).Family(wxFONTFAMILY_DEFAULT).FaceName(family));
    previewTextCtrl->SetFont(font);
}
 
void wxOptionDialog::OnOkButtonClicked(wxCommandEvent& _event)
{
    MyCustomEvent event(MY_CUSTOM_EVENT);
    event.SetMyData("여기에 전달하고 싶은 데이터");
    wxPostEvent(GetParent(), event); // 부모 윈도우에 이벤트 전달
 
    EndModal(wxID_OK);
}
cs

 

 

 이렇게 하면, 미리보기용 TextCotrl에서 Font에 맞춰서 적용이 가능하다.

 이 소스에서는 FontStyle에 관련된건 제외하고, FontFamily와 Font Size만 적용해 놓은 상태인데.

 ComboBox의 변화를 인식하는 OnFontChange에 맞춰서 동작하도록 만들었고, 그럴 처리하기 위한 UpDatePreview라는 함수에서 적용해서 미리보기를 갱신할 수 있다.

 

 여기서 Event로 전송하기 위해서는

 wxOptionsDialog.h

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
31
32
33
34
35
36
37
38
39
40
41
42
43
#pragma once
 
#include <wx/wx.h>
#include <wx/combobox.h>
#include <wx/fontenum.h>
 
#include <wx/sizer.h>
 
#include "wxMyCustomEvent.h"
 
#ifndef __WX_WIDGETS_OPTION_DIALOG_H__
#define __WX_WIDGETS_OPTION_DIALOG_H__
 
// ID 값 정의
enum
{
    ID_Options = wxID_HIGHEST + 1 // 사용자 정의 ID
};
 
class wxOptionDialog : public wxDialog
{
public:
    wxOptionDialog(wxWindow* parent, wxWindowID id, const wxString& title,
        const wxPoint& pos = wxDefaultPosition,
        const wxSize& size = wxDefaultSize,
        long style = wxDEFAULT_DIALOG_STYLE);
 
private:
    void OnOkButtonClicked(wxCommandEvent& evnt);
 
    void OnFontChange(wxCommandEvent& evnt);
    void UpdatePreview();
 
 
    wxComboBox* familyComboBox;
    wxComboBox* styleComboBox;
    wxComboBox* sizeComboBox;
 
    wxTextCtrl* previewTextCtrl;
    wxFont font;
};
 
#endif
cs

 

 이렇게 해서 wxFont font;를 추가해주고

 

 wxMyCustomEvent.h에는

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
31
32
33
34
35
36
37
38
#pragma once
 
// wxMyCusomEvent.h
#pragma once
#include <wx/wx.h>
#include <wx/event.h>
 
#ifndef __WX_MY_CUSTOM_EVENT_H__
#define __WX_MY_CUSTOM_EVENT_H__
 
class MyCustomEvent : public wxCommandEvent
{
public:
    MyCustomEvent(wxEventType commandType = wxEVT_NULL, int id = 0)
        : wxCommandEvent(commandType, id) { }
 
    // 복사 생성자 - 이벤트 시스템에서 이벤트 복사 시 필요
    MyCustomEvent(const MyCustomEvent& event)
        : wxCommandEvent(event), myData(event.myData) { }
 
    // wxEvent의 Clone() 메서드 구현 - 이벤트 시스템에서 필요
    virtual wxEvent* Clone() const override { return new MyCustomEvent(*this); }
 
    // 데이터 설정 및 가져오기 메서드
    void SetMyData(const wxString& data);
    const wxString GetMyData(void) ;
    void SetwxFont(const wxFont& data) { m_font = data; }
    wxFont GetwxFont() const { return m_font; }
 
private:
    wxString myData; // 전달하고자 하는 데이터
    wxFont m_font;
};
 
#endif
 
// 사용자 정의 이벤트 타입 선언
wxDECLARE_EVENT(MY_CUSTOM_EVENT, MyCustomEvent);
cs

 

 이렇게 해서 font를 이벤트에 적용할 수 있게 해야한다.

 

 이후 wxOptinosDialog.cpp에서 

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
 
#include <wx/wx.h>
 
#include "wxOptionsDialog.h"
 
wxOptionDialog::wxOptionDialog(wxWindow* parent, wxWindowID id, const wxString& title,
    const wxPoint& pos,
    const wxSize& size,
    long style)
    : wxDialog(parent, id, title, pos, size, style) {
 
    // 컨트롤을 담을 메인 사이저 생성
    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
 
    // 설정 대화 상자의 내용을 여기에 구성
    // 폰트 패밀리 선택 콤보박스
    wxArrayString fontFamilies = wxFontEnumerator::GetFacenames();
    familyComboBox = new wxComboBox(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, fontFamilies, wxCB_READONLY);
    mainSizer->Add(new wxStaticText(this, wxID_ANY, wxT("폰트(E):")), 0, wxLEFT | wxTOP, 5);
    mainSizer->Add(familyComboBox, 0, wxLEFT | wxEXPAND, 5);
 
    // 폰트 스타일 선택 콤보박스
    wxArrayString fontStyles;
    fontStyles.Add("보통");
    fontStyles.Add("기울임꼴");
    fontStyles.Add("두껍게");
    styleComboBox = new wxComboBox(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, fontStyles, wxCB_READONLY);
    mainSizer->Add(new wxStaticText(this, wxID_ANY, wxT("폰트 스타일(Y):")), 0, wxLEFT | wxTOP, 5);
    mainSizer->Add(styleComboBox, 0, wxLEFT | wxEXPAND, 5);
 
    // 폰트 크기 선택 콤보박스
    wxArrayString fontSizes;
    for (int i = 8; i < 30++i)
        fontSizes.Add(wxString::Format(wxT("%d"), i));
    sizeComboBox = new wxComboBox(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, fontSizes, wxCB_READONLY);
    mainSizer->Add(new wxStaticText(this, wxID_ANY, wxT("크기(S):")), 0, wxLEFT | wxTOP, 5);
    mainSizer->Add(sizeComboBox, 0, wxLEFT | wxEXPAND, 5);
 
    // 폰트 미리보기
    previewTextCtrl = new wxTextCtrl(this, wxID_ANY, wxT("AaBbYyZz"), wxDefaultPosition, wxDefaultSize, wxTE_CENTER);
    mainSizer->Add(new wxStaticText(this, wxID_ANY, wxT("보기")), 0, wxLEFT | wxTOP, 5);
    mainSizer->Add(previewTextCtrl, 1, wxLEFT | wxEXPAND, 5);
 
    // OK 및 Cancel 버튼 추가
    wxSizer* buttonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
    mainSizer->Add(buttonSizer, 0, wxALL | wxCENTER, 10);
 
    // 메인 사이저를 대화 상자에 설정
    SetSizer(mainSizer);
    mainSizer->SetSizeHints(this); // 이 호출은 대화 상자가 최소 크기로 축소되지 않도록 합니다.
 
    // 이벤트 처리기 등록
    Bind(wxEVT_BUTTON, &wxOptionDialog::OnOkButtonClicked, this, wxID_OK);
 
    // 이벤트 처리기 등록
    Bind(wxEVT_COMBOBOX, &wxOptionDialog::OnFontChange, this, wxID_ANY);
}
 
void wxOptionDialog::OnFontChange(wxCommandEvent& event)
{
    UpdatePreview();
}
 
void wxOptionDialog::UpdatePreview()
{
    wxString family = familyComboBox->GetValue();
    wxString styleName = styleComboBox->GetValue();
    wxString sizeStr = sizeComboBox->GetValue();
    long size;
    if (!sizeStr.ToLong(&size)) return// 크기 변환 실패 시 리턴
 
    wxFont updatedFont(wxFontInfo(size).Family(wxFONTFAMILY_DEFAULT).FaceName(family));
    this->font = updatedFont; // 멤버 변수에 폰트 저장
    previewTextCtrl->SetFont(font);
}
 
void wxOptionDialog::OnOkButtonClicked(wxCommandEvent& _event)
{
    MyCustomEvent event(MY_CUSTOM_EVENT);
    event.SetwxFont(font);
    wxPostEvent(GetParent(), event); // 부모 윈도우에 이벤트 전달
 
    EndModal(wxID_OK);
}
cs

 

 이렇게 수정하여, font의 정보를 전송하는 기능을 제공할 수 있게 된다.

Posted by JunkMam
,

 wxWidgets에서 Event을 전송하는 방법을 작성했는데.

 필요한 정보를 저장하거나 필요한 정보를 전송해야되는 경우에는 제한이 걸릴 수도 있다.

 여기서 사용자가 원하는 Event을 제작하는 것이 있을 수 있다.

 

 다음과 같이 사용하면, Custom Event을 만들 수 있다.

 이벤트를 선언 및 정의를 하기 위해서 wxMyCustomEvent.h와 wxMyCustomEvent.cpp을 만들어 둔다.

 

 wxMyCustomEvent.h

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
31
32
33
34
35
36
37
#pragma once
 
// wxMyCusomEvent.h
#pragma once
#include <wx/wx.h>
#include <wx/event.h>
 
#ifndef __WX_MY_CUSTOM_EVENT_H__
#define __WX_MY_CUSTOM_EVENT_H__
 
class MyCustomEvent : public wxCommandEvent
{
public:
    MyCustomEvent(wxEventType commandType = wxEVT_NULL, int id = 0)
        : wxCommandEvent(commandType, id) { }
 
    // 복사 생성자 - 이벤트 시스템에서 이벤트 복사 시 필요
    MyCustomEvent(const MyCustomEvent& event)
        : wxCommandEvent(event), myData(event.myData) { }
 
    // wxEvent의 Clone() 메서드 구현 - 이벤트 시스템에서 필요
    virtual wxEvent* Clone() const override { return new MyCustomEvent(*this); }
 
    // 데이터 설정 및 가져오기 메서드
    void SetMyData(const wxString& data);
    const wxString GetMyData(void) ;
    //void SetMyData(const wxString& data) { myData = data; }
    //wxString GetMyData() const { return myData; }
 
private:
    wxString myData; // 전달하고자 하는 데이터
};
 
#endif
 
// 사용자 정의 이벤트 타입 선언
wxDECLARE_EVENT(MY_CUSTOM_EVENT, MyCustomEvent);
cs

 

 여기서 wxDECLEAR_EVENT라는 매크로는 해당 이벤트를 삭제하는 것으로 정의를 반복하는걸 방지 할 수도 있다.

 

 wxMyCustomEvent.cpp

 

 

 여기서 Event을 정의하는 wxDEFINE_EVENT라는 매크로를 이용해서 이벤트를 주고 받는데 도움을 받을 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
 
#include "wxMyCustomEvent.h"
 
// 사용자 정의 이벤트 타입 선언
wxDEFINE_EVENT(MY_CUSTOM_EVENT, MyCustomEvent);
 
void MyCustomEvent::SetMyData(const wxString& data) {
    myData = data;
}
 
const wxString MyCustomEvent::GetMyData(void) {
    return myData;
}
cs

 

 이렇게 해서 CustomEvent을 선언 및 정의를 할 수 있다.

 

 이걸 이용해서 적용하기 위해서 다음과 같이 적용한다면, 

 wxOptionsDialog.h

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
31
32
33
#pragma once
 
#include <wx/wx.h>
#include <wx/combobox.h>
#include <wx/fontenum.h>
 
#include <wx/sizer.h>
 
#include "wxMyCustomEvent.h"
 
#ifndef __WX_WIDGETS_OPTION_DIALOG_H__
#define __WX_WIDGETS_OPTION_DIALOG_H__
 
// ID 값 정의
enum
{
    ID_Options = wxID_HIGHEST + 1 // 사용자 정의 ID
};
 
class wxOptionDialog : public wxDialog
{
public:
    wxOptionDialog(wxWindow* parent, wxWindowID id, const wxString& title,
        const wxPoint& pos = wxDefaultPosition,
        const wxSize& size = wxDefaultSize,
        long style = wxDEFAULT_DIALOG_STYLE);
 
private:
    void OnOkButtonClicked(wxCommandEvent& evnt);
 
};
 
#endif
cs

 

 wxOptionDialog.cpp

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 
#include <wx/wx.h>
 
#include "wxOptionsDialog.h"
 
wxOptionDialog::wxOptionDialog(wxWindow* parent, wxWindowID id, const wxString& title,
    const wxPoint& pos,
    const wxSize& size,
    long style)
    : wxDialog(parent, id, title, pos, size, style) {
 
    // 컨트롤을 담을 메인 사이저 생성
    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
 
    // 설정 대화 상자의 내용을 여기에 구성
    // 예: 설정 옵션을 위한 컨트롤 추가
    wxStaticText* staticText = new wxStaticText(this, wxID_ANY, "Font Family", wxPoint(2020), wxDefaultSize);
    mainSizer->Add(staticText, 0, wxALL, 10);
 
    // 콤보박스 생성 및 옵션 추가
    wxComboBox* comboBox = new wxComboBox(this, wxID_ANY, "", wxPoint(2050), wxSize(150-1));
 
    // 사용 가능한 폰트 패밀리 목록을 가져옵니다.
    wxArrayString fontFamilies = wxFontEnumerator::GetFacenames(wxFONTENCODING_SYSTEM, false);
 
    // 콤보박스에 폰트 패밀리를 추가합니다. foreach문 사용.
    for (const wxString& fontFamily : fontFamilies) {
        comboBox->Append(fontFamily);
    }
 
    mainSizer->Add(comboBox, 0, wxALL | wxEXPAND, 10);
 
    // OK 및 Cancel 버튼 추가
    wxSizer* buttonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
    mainSizer->Add(buttonSizer, 0, wxALL | wxCENTER, 10);
 
    // 메인 사이저를 대화 상자에 설정
    SetSizer(mainSizer);
    mainSizer->SetSizeHints(this); // 이 호출은 대화 상자가 최소 크기로 축소되지 않도록 합니다.
 
    // 이벤트 처리기 등록
    Bind(wxEVT_BUTTON, &wxOptionDialog::OnOkButtonClicked, this, wxID_OK);
}
 
void wxOptionDialog::OnOkButtonClicked(wxCommandEvent& _event)
{
    MyCustomEvent event(MY_CUSTOM_EVENT);
    event.SetMyData("여기에 전달하고 싶은 데이터");
    wxPostEvent(GetParent(), event); // 부모 윈도우에 이벤트 전달
 
    EndModal(wxID_OK);
}
cs

 

 정의해서 불러오는 Event을 wxMain.cpp로 받는 방법이 있다.

 

 wxMain.cpp

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "wxMain.h"
 
wxIMPLEMENT_APP(MyApp);
 
bool MyApp::OnInit()
{
    MyFrame* frame = new MyFrame("Serial Graph");
    frame->Show(true);
    return true;
}
 
MyFrame::MyFrame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
    wxMenu* menuFile = new wxMenu;
    menuFile->Append(wxID_OPEN, "&Open\tCtrl-O""Open a file");
    menuFile->Append(wxID_SAVE, "&Save\tCtrl-S""Save the file");
    menuFile->AppendSeparator();
    menuFile->Append(ID_QUIT, "E&xit\tAlt-X""프로그램 종료");
 
    wxMenu* menuOptions = new wxMenu;
    menuOptions->Append(ID_Options, "&Options""Options Setting");
 
    wxMenuBar* menuBar = new wxMenuBar;
    menuBar->Append(menuFile, "&File");
    menuBar->Append(menuOptions, "&Options");
 
    SetMenuBar(menuBar);
 
    textControl = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
 
    // sizer를 생성하여 텍스트 컨트롤의 크기를 조정합니다.
    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(textControl, 1, wxEXPAND | wxALL, 0); // wxEXPAND는 컨트롤이 sizer의 가능한 모든 공간을 차지하도록 합니다. 1은 비율을 의미하며, 이 경우 다른 컨트롤이 없으므로 전체 크기를 차지합니다.
 
    // 프레임에 sizer를 설정합니다.
    this->SetSizer(sizer);
    this->Layout(); // sizer를 강제로 다시 계산하여 적용합니다.
 
    // 폰트 설정
    wxFont* font = new wxFont(16, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
    textControl->SetFont(*font);
 
    CreateStatusBar();
    SetStatusText("Ready");
 
    // 이벤트 핸들러 연결
    Bind(wxEVT_MENU, &MyFrame::OnQuit, this, ID_QUIT);
    Bind(wxEVT_MENU, &MyFrame::OnOpen, this, wxID_OPEN);
    Bind(wxEVT_MENU, &MyFrame::OnSave, this, wxID_SAVE);
 
    Bind(wxEVT_MENU, &MyFrame::OnSettings, this, ID_Options);
 
    // 이벤트 처리기 등록
    Bind(MY_CUSTOM_EVENT, &MyFrame::OnMyCustomEvent, this);
}
 
void MyFrame::OnQuit(wxCommandEvent& event)
{
    Close(true);
}
 
void MyFrame::OnOpen(wxCommandEvent& event)
{
    wxFileDialog openFileDialog(this, _("Open TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
    if (openFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    std::ifstream file(openFileDialog.GetPath().ToStdString());
    // 파일을 열고 텍스트 컨트롤에 내용을 로드합니다.
    if (textControl->LoadFile(openFileDialog.GetPath())) {
        std::stringstream buffer;
        buffer << file.rdbuf(); // 파일의 내용을 buffer에 읽어 들입니다.
        file.close(); // 파일을 닫습니다.
 
        // textControl의 내용을 갱신합니다.
        textControl->SetValue(buffer.str());
        //textControl->SetLabelText(buffer.str());
        // 타이틀을 열린 파일의 이름으로 설정합니다.
        SetTitle(openFileDialog.GetFilename());
 
    }
    else {
        wxMessageBox("Cannot open File!""Error", wxOK | wxICON_ERROR);
    }
}
 
void MyFrame::OnSave(wxCommandEvent& event)
{
    wxFileDialog saveFileDialog(this, _("Save TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
    if (saveFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    // 현재 텍스트 컨트롤의 내용을 파일에 저장합니다.
    textControl->SaveFile(saveFileDialog.GetPath());
}
 
void MyFrame::OnSettings(wxCommandEvent& event)
{
    dialog = new wxOptionDialog(this, wxID_ANY, "Settings");
    dialog->ShowModal();
 
    //if (dialog.ShowModal() == wxID_OK)
    //{
    //    // 사용자가 설정을 변경하고 OK를 클릭했을 때의 처리
    //    SetStatusText("Settings Updated");
    //}
}
 
// 이벤트 처리 함수 구현
void MyFrame::OnMyCustomEvent(MyCustomEvent& event)
{
    wxString info = event.GetMyData();
    // 이벤트와 함께 전달된 정보 처리
    wxMessageBox(info, "이벤트 정보", wxOK | wxICON_INFORMATION);
    delete dialog;
}
cs

 

 이렇게 이벤트를 처리할 수 있게 된다.

 

Posted by JunkMam
,

 Options에서 설정한 정보를 Main에 있는 textCtrl에게 적용하기 위해서 정보를 주고 받아야되는데.

 여기서 간단하게 이벤트를 주고 받는 방법이 있다.

 

 간단한 이벤트를 정의 하기 위해서는 

1
wxDECLARE_EVENT(MY_CUSTOM_EVENT_TYPE, wxCommandEvent);
cs

 

 

 이 '매크로'를 사용한다.

 

 wxOptions.h

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
31
32
33
34
35
36
#pragma once
 
#include <wx/wx.h>
#include <wx/combobox.h>
#include <wx/fontenum.h>
 
#include <wx/sizer.h>
 
#include <wx/event.h>
 
#ifndef __WX_WIDGETS_OPTION_DIALOG_H__
#define __WX_WIDGETS_OPTION_DIALOG_H__
 
// 사용자 정의 이벤트 타입 정의
wxDECLARE_EVENT(wxEVT_COMMAND_MY_CUSTOM_EVENT, wxCommandEvent);
 
// ID 값 정의
enum
{
    ID_Options = wxID_HIGHEST + 1 // 사용자 정의 ID
};
 
class wxOptionDialog : public wxDialog
{
public:
    wxOptionDialog(wxWindow* parent, wxWindowID id, const wxString& title,
        const wxPoint& pos = wxDefaultPosition,
        const wxSize& size = wxDefaultSize,
        long style = wxDEFAULT_DIALOG_STYLE);
 
private:
    void OnOkButtonClicked(wxCommandEvent& evnt);
 
};
 
#endif
cs

 

 wxOptions.cpp

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 
#include <wx/wx.h>
 
#include "wxOptionsDialog.h"
 
// 사용자 정의 이벤트 타입 구현
wxDEFINE_EVENT(wxEVT_COMMAND_MY_CUSTOM_EVENT, wxCommandEvent);
 
wxOptionDialog::wxOptionDialog(wxWindow* parent, wxWindowID id, const wxString& title,
    const wxPoint& pos,
    const wxSize& size,
    long style)
    : wxDialog(parent, id, title, pos, size, style) {
 
    // 컨트롤을 담을 메인 사이저 생성
    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
 
    // 설정 대화 상자의 내용을 여기에 구성
    // 예: 설정 옵션을 위한 컨트롤 추가
    wxStaticText* staticText = new wxStaticText(this, wxID_ANY, "Font Family", wxPoint(2020), wxDefaultSize);
    mainSizer->Add(staticText, 0, wxALL, 10);
 
    // 콤보박스 생성 및 옵션 추가
    wxComboBox* comboBox = new wxComboBox(this, wxID_ANY, "", wxPoint(2050), wxSize(150-1));
 
    // 사용 가능한 폰트 패밀리 목록을 가져옵니다.
    wxArrayString fontFamilies = wxFontEnumerator::GetFacenames(wxFONTENCODING_SYSTEM, false);
 
    // 콤보박스에 폰트 패밀리를 추가합니다. foreach문 사용.
    for (const wxString& fontFamily : fontFamilies) {
        comboBox->Append(fontFamily);
    }
 
    mainSizer->Add(comboBox, 0, wxALL | wxEXPAND, 10);
 
    // OK 및 Cancel 버튼 추가
    wxSizer* buttonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
    mainSizer->Add(buttonSizer, 0, wxALL | wxCENTER, 10);
 
    // 메인 사이저를 대화 상자에 설정
    SetSizer(mainSizer);
    mainSizer->SetSizeHints(this); // 이 호출은 대화 상자가 최소 크기로 축소되지 않도록 합니다.
 
    // 이벤트 처리기 등록
    Bind(wxEVT_BUTTON, &wxOptionDialog::OnOkButtonClicked, this, wxID_OK);
}
 
void wxOptionDialog::OnOkButtonClicked(wxCommandEvent& event)
{
    // 사용자 정의 이벤트 생성
    wxCommandEvent myEvent(wxEVT_COMMAND_MY_CUSTOM_EVENT);
    myEvent.SetString("여기에 정보를 설정"); // 필요한 정보를 이벤트와 함께 전달
    // 메인 윈도우에 이벤트 전달
    wxPostEvent(GetParent(), myEvent);
 
    // 다이얼로그 닫기
    EndModal(wxID_OK);
}
cs

 

 

 이렇게 하면, 메인 윈도우인 wxMain.cpp에 이벤트를 전달하여, 정보를 전송할 수 있다.

 

 그리고, 이 이벤트를 받기 위해서 Binding을 해줘야하는데.

 

 wxMain.h

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#pragma once
#include "wx/wx.h"
#include <wx/filedlg.h>
#include <wx/textctrl.h>
#include <wx/splitter.h>
 
// 파일을 읽어 들이기 위한 용도.
#include <fstream>
#include <sstream>
 
#include "wxOptionsDialog.h"
 
enum
{
    ID_QUIT,
};
 
enum {
    MY_EVENT_ID = 10001,
};
 
// ID 값 정의
enum
{
    ID_Settings_Menu = wxID_HIGHEST + 1 // 사용자 정의 ID
};
 
class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};
 
class MyFrame : public wxFrame
{
public:
    MyFrame(const wxString& title);
 
    void OnQuit(wxCommandEvent& event);
 
private:
    wxTextCtrl* textControl;
 
    void OnOpen(wxCommandEvent& event);
    void OnSave(wxCommandEvent& event);
    void OnButtonClick(wxCommandEvent& event);
 
    // 세팅 창을 띄우기 위한 메소드
    void OnSettings(wxCommandEvent& event);
 
    // 이벤트를 받기 위한 메소드
    void OnMyCustomEvent(wxCommandEvent& event);
};
 
cs

 

 wxMain.cpp

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "wxMain.h"
 
wxIMPLEMENT_APP(MyApp);
 
bool MyApp::OnInit()
{
    MyFrame* frame = new MyFrame("Serial Graph");
    frame->Show(true);
    return true;
}
 
MyFrame::MyFrame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
    wxMenu* menuFile = new wxMenu;
    menuFile->Append(wxID_OPEN, "&Open\tCtrl-O""Open a file");
    menuFile->Append(wxID_SAVE, "&Save\tCtrl-S""Save the file");
    menuFile->AppendSeparator();
    menuFile->Append(ID_QUIT, "E&xit\tAlt-X""프로그램 종료");
 
    wxMenu* menuOptions = new wxMenu;
    menuOptions->Append(ID_Options, "&Options""Options Setting");
 
    wxMenuBar* menuBar = new wxMenuBar;
    menuBar->Append(menuFile, "&File");
    menuBar->Append(menuOptions, "&Options");
 
    SetMenuBar(menuBar);
 
    textControl = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
 
    // sizer를 생성하여 텍스트 컨트롤의 크기를 조정합니다.
    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(textControl, 1, wxEXPAND | wxALL, 0); // wxEXPAND는 컨트롤이 sizer의 가능한 모든 공간을 차지하도록 합니다. 1은 비율을 의미하며, 이 경우 다른 컨트롤이 없으므로 전체 크기를 차지합니다.
 
    // 프레임에 sizer를 설정합니다.
    this->SetSizer(sizer);
    this->Layout(); // sizer를 강제로 다시 계산하여 적용합니다.
 
    // 폰트 설정
    wxFont* font = new wxFont(16, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
    textControl->SetFont(*font);
 
    CreateStatusBar();
    SetStatusText("Ready");
 
    // 이벤트 핸들러 연결
    Bind(wxEVT_MENU, &MyFrame::OnQuit, this, ID_QUIT);
    Bind(wxEVT_MENU, &MyFrame::OnOpen, this, wxID_OPEN);
    Bind(wxEVT_MENU, &MyFrame::OnSave, this, wxID_SAVE);
 
    Bind(wxEVT_MENU, &MyFrame::OnSettings, this, ID_Options);
 
    // 이벤트 처리기 등록
    Bind(wxEVT_COMMAND_MY_CUSTOM_EVENT, &MyFrame::OnMyCustomEvent, this);
}
 
void MyFrame::OnQuit(wxCommandEvent& event)
{
    Close(true);
}
 
void MyFrame::OnOpen(wxCommandEvent& event)
{
    wxFileDialog openFileDialog(this, _("Open TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
    if (openFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    std::ifstream file(openFileDialog.GetPath().ToStdString());
    // 파일을 열고 텍스트 컨트롤에 내용을 로드합니다.
    if (textControl->LoadFile(openFileDialog.GetPath())) {
        std::stringstream buffer;
        buffer << file.rdbuf(); // 파일의 내용을 buffer에 읽어 들입니다.
        file.close(); // 파일을 닫습니다.
 
        // textControl의 내용을 갱신합니다.
        textControl->SetValue(buffer.str());
        //textControl->SetLabelText(buffer.str());
        // 타이틀을 열린 파일의 이름으로 설정합니다.
        SetTitle(openFileDialog.GetFilename());
 
    }
    else {
        wxMessageBox("Cannot open File!""Error", wxOK | wxICON_ERROR);
    }
}
 
void MyFrame::OnSave(wxCommandEvent& event)
{
    wxFileDialog saveFileDialog(this, _("Save TXT file"), """",
        "TXT files (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
    if (saveFileDialog.ShowModal() == wxID_CANCEL)
        return// 사용자가 취소했을 때
 
    // 현재 텍스트 컨트롤의 내용을 파일에 저장합니다.
    textControl->SaveFile(saveFileDialog.GetPath());
}
 
void MyFrame::OnSettings(wxCommandEvent& event)
{
    wxOptionDialog dialog(this, wxID_ANY, "Settings");
    dialog.ShowModal();
 
    //if (dialog.ShowModal() == wxID_OK)
    //{
    //    // 사용자가 설정을 변경하고 OK를 클릭했을 때의 처리
    //    SetStatusText("Settings Updated");
    //}
 
 
}
 
// 이벤트 처리 함수 구현
void MyFrame::OnMyCustomEvent(wxCommandEvent& event)
{
    wxString info = event.GetString();
    // 이벤트와 함께 전달된 정보 처리
    wxMessageBox(info, "이벤트 정보", wxOK | wxICON_INFORMATION);
}
cs

 

 

 이렇게 하면, OnMyCustomEvent라는 함수로 사용자가 적용한 이벤트의 정보가 오가게 된다.

Posted by JunkMam
,