찾기(Find)을 구현하기 위해서는 문자열 비교 및 검색 기능을 구현해야되는데.

 wxWidgets에서는 기본적으로 제공해준다.

 여기서 wxFindReplaceDialog라는 창을 제공해주는데.

 이걸 사용하기 위해선 'fdrepdlg.h' 라는 헤더 파일을 포함해줘야한다.

 

wxMain.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
// Find Dialog
#include <wx/fdrepdlg.h>
 
class MyFrame : public wxFrame
{
public:
    ...
private:
    // 메모장 기능해주는 장치.
    wxTextCtrl* m_textControl;
 
    // 찾기 기능을 처리하기 위한 창.
    wxFindReplaceDialog* m_findDialog;
    wxFindReplaceData m_findData; // 찾기 및 바꾸기 데이터.
 
    ...
};
cs

 

이렇게 하면, wxFindReplaceDialog의 창을 불러와서 특정 문자열을 찾아서 제공하도록 할 수 있다.

 

이제, Edit의 하위 메뉴인 Find를 처리해주는 이벤트 핸들러와 Dialog로 데이터를 제공 받는 이벤트 핸들러들을 만든다.

Find를 처리해주는 이벤트 핸들러를 OnFind라고 하고,

FindReplace의 이벤트 핸들러는 OnFindClose, OnFindNext로 한다.

 

wxMain.h

1
2
3
4
    void OnFind(wxCommandEvent& event);
    // FindDialog 이벤트를 받는 핸들러
    void OnFindClose(wxFindDialogEvent& event); // FindDialog가 닫혔을시.
    void OnFindNext(wxFindDialogEvent& event); // FindDialog로 다음 문자을 검색할시.
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
26
27
28
29
30
    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(wxID_CUT, "Cu&t\tCtrl+X""Cut the selected text to the clipboard");
    m_menuEdit->Append(wxID_COPY, "&Copy\tCtrl+C""Copy the selected text to the clipboard");
    m_menuEdit->Append(wxID_PASTE, "&Paste\tCtrl+V""Paste text from the clipboard");
    m_menuFile->AppendSeparator();
    m_menuEdit->Append(wxID_FIND, "&Findl\tCtrl+F""Find text");
    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");
 
    // 메뉴 Edit에 관련된 이벤트 핸들러
    Bind(wxEVT_MENU, &MyFrame::OnUndo, this, wxID_UNDO);
    Bind(wxEVT_MENU, &MyFrame::OnRedo, this, wxID_REDO);
    Bind(wxEVT_MENU, &MyFrame::OnCut, this, wxID_CUT);
    Bind(wxEVT_MENU, &MyFrame::OnCopy, this, wxID_COPY);
    Bind(wxEVT_MENU, &MyFrame::OnPaste, this, wxID_PASTE);
 
    Bind(wxEVT_MENU, &MyFrame::OnFind, this, wxID_FIND);
 
    Bind(wxEVT_MENU, &MyFrame::OnSelectAll, this, ID_DATETIME);
    Bind(wxEVT_MENU, &MyFrame::OnInsertDateTime, this, ID_DATETIME);
 
 
    // FindDialog 이벤트 핸들러 적용.
    Bind(wxEVT_FIND_CLOSE, &MyFrame::OnFindClose, this);
    Bind(wxEVT_FIND, &MyFrame::OnFindNext, this);
cs

 

이제, 이벤트 핸들러를 구현한다.

먼저 Find 메뉴를 처리하는 이벤트 핸들러의 구현은 다음과 같이 한다.

1
2
3
4
5
6
void MyFrame::OnFind(wxCommandEvent& event) {
    if (!m_findDialog) {
        m_findDialog = new wxFindReplaceDialog(this&m_findData, "Find");
        m_findDialog->Show(true);
    }
}
cs

 

이후에 FindReplaceDialog를 처리하기 위한 이벤트 핸들러는 다음과 같이 한다.

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
// FindDialog를 닫았을때 처리하는 이벤트
void MyFrame::OnFindClose(wxFindDialogEvent& event) {
    m_findDialog->Destroy();
    m_findDialog = nullptr;
}
 
// FindDialog를 다음 문자을 검색했을때 처리하는 이벤트
void MyFrame::OnFindNext(wxFindDialogEvent& event){
    wxString searchString = event.GetFindString();
    int flags = event.GetFlags();
 
    // 검색 시작 위치를 결정합니다.
    long startPos = m_textControl->GetInsertionPoint();
    long textLength = m_textControl->GetValue().length();
 
    // 대소문자 구분 여부를 확인합니다.
    wxString textToSearch = m_textControl->GetValue();
    if (!(flags & wxFR_MATCHCASE))
    {
        textToSearch.MakeLower();
        searchString.MakeLower();
    }
 
    // 검색을 시작합니다.
    long foundPos = -1;
    if (flags & wxFR_DOWN) // "다음 찾기"인 경우
    {
        foundPos = textToSearch.find(searchString, startPos);
        // 검색된 위치가 현재 커서 위치보다 앞인 경우 다음 위치부터 다시 검색
        if (foundPos == startPos) {
            foundPos = textToSearch.find(searchString, startPos + 1);
        };
    }
    else // "이전 찾기"인 경우 (옵션에 따라)
    {
        wxString textToStartPos = textToSearch.Mid(0, startPos);
        foundPos = textToStartPos.rfind(searchString);
    }
 
    if (foundPos != wxString::npos)
    {
        m_textControl->ShowPosition(foundPos);
    }
    else
    {
        wxMessageBox("Search string not found.""Find", wxOK | wxICON_INFORMATION);
    }
}
cs

 

여기서, OnFindClose는 FindReplaceDialog가 종료되면, 반환하도록 만들어서 창을 제거하도록 만든다.

OnFindNext는 FindReplaceDialog의 상태를 보고 거기에 맞춰 검색하도록 하는 장치이다.

단어를 선택하지 않고, 현재 위치로 이동하여 자동으로 스크롤로 이동하도록 만든다.

Posted by JunkMam
,

 C에서는 동작하는 과정을 나눠지는 기능으로 제공하는 '조건문'이 있다.

 참과 거짓으로 처리하는 if문과 특정 값에서 이동하는 switch문이 있다.

 

 if문

 if문은 if( 조건 ) 으로 구성되며, 조건이 참(0이외의 값)과 거짓(0)으로 적용된다.

1
2
3
if( a ){
 // a가 1이상일경우.
}
cs

 

이렇게 되면, // a가 1이상일 경우에 관련된 동작을 작업할 수 있다.

조건에 맞지 않을 경우엔 else을 사용한다.

1
2
3
4
5
if( a ){
 // a가 1이상일경우.
}else{
 // a가 0일 경우.
}
cs

 

여기서 조건이 맞지 않았지만, 다른 조건일때 처리하는 방법으론 else뒤에 if(조건)을 넣는다.

1
2
3
4
5
6
7
if( a ){
 // a가 1이상일경우.
}else if( b ){
 // a가 0이지만, b는 1이상일 경우.
}else{
 // a와 b가 모두 다 0일 경우.
}
cs

 

여기서 이런 경우가 있을 수 있다.

 a가 1, 2, ,3 ,4가 될 경우가 있다고 해보자.

그러면, if문을 사용할 경우엔 다음과 같아진다.

1
2
3
4
5
6
7
8
9
if( a == 1 ){
 // a가 1일때
}else if( a == 2 ){
 // a가 2일때
}else if( a == 3 ){
 // a가 3일때
}else if( a == 4 ){
 // a가 4일때
}
cs

 

이럴때, if else로 조건문을 매번 확인해서 이동하는 것이 아니라.

특정 값에만 이동하도록 만드는 방법이 있는데.

그것이 바로 switch문이다.

 

switch문은 다음과 같이 적용된다.

1
2
3
4
5
6
7
8
9
switch( 값 ){
case 특정값:{
    break;
}
default:{
    // 값이 프로그래머가 정의 내리지 않는 값일 경우.
    break;
}
}
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
26
27
28
29
30
31
#include <stdio.h>
 
#include <stdlib.h>
 
int main(int argc, char** argv){
    unsigned int a = 0;
    unsigned char steps = atoi(argv[1]);
 
    if(steps > 3){
        a = 100;
    }else{
        switch(steps){
        case 0:{
            a++;
            break;
        }
        case 1:
        case 2:{
            a = 5;
            break;
        }
        case 3:{
            a = 15;
            break;
        }
        }
    }
    printf("a: %d", a);
    return 0;
}
 
cs

 

 

 이렇게 하면,

 실행파일 뒤에 추가적으로 넣은 argv의 값을 보고(숫자가 들어가야된다.), 그 값에 맞춰서 a의 값을 정하여 값이 출력하게 된다.

 

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

[C] 연산자  (0) 2024.02.16
[C] 상수와 변수  (0) 2024.02.15
[C] 기본적으로 지원해주는 출력  (0) 2024.02.14
[C] 기본 구조  (1) 2024.02.13
Posted by JunkMam
,

 wxMain.h에는 이벤트 핸들러를 추가해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
    // Edit 메뉴에 적용할 이벤트 핸들러
    void OnUndo(wxCommandEvent& event);
    void OnRedo(wxCommandEvent& event);
    void OnCut(wxCommandEvent& event);
    void OnCopy(wxCommandEvent& event);
    void OnPaste(wxCommandEvent& event);
 
 
    // 메뉴 동적 활성화 하기 위한 이벤트 핸들러
    void OnUpdateUndo(wxUpdateUIEvent& event);
    void OnUpdateRedo(wxUpdateUIEvent& event);
 
    void OnUpdateCut(wxUpdateUIEvent& event);
    void OnUpdateCopy(wxUpdateUIEvent& event);
    void OnUpdatePaste(wxUpdateUIEvent& event);
cs

 

 wxMain.cpp에는 메뉴 추가 및 이벤트 핸들러를 연결한다.

1
2
3
4
5
6
7
8
9
10
    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(wxID_CUT, "Cu&t\tCtrl+X""Cut the selected text to the clipboard");
    m_menuEdit->Append(wxID_COPY, "&Copy\tCtrl+C""Copy the selected text to the clipboard");
    m_menuEdit->Append(wxID_PASTE, "&Paste\tCtrl+V""Paste text from the clipboard");
    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
5
6
7
8
9
10
11
12
13
14
15
16
17
    // 메뉴 Edit에 관련된 이벤트 핸들러
    Bind(wxEVT_MENU, &MyFrame::OnUndo, this, wxID_UNDO);
    Bind(wxEVT_MENU, &MyFrame::OnRedo, this, wxID_REDO);
    Bind(wxEVT_MENU, &MyFrame::OnCut, this, wxID_CUT);
    Bind(wxEVT_MENU, &MyFrame::OnCopy, this, wxID_COPY);
    Bind(wxEVT_MENU, &MyFrame::OnPaste, this, wxID_PASTE);
    Bind(wxEVT_MENU, &MyFrame::OnSelectAll, this, ID_DATETIME);
    Bind(wxEVT_MENU, &MyFrame::OnInsertDateTime, this, ID_DATETIME);
 
 
    // 메뉴바 갱신 이벤트 핸들러
    Bind(wxEVT_UPDATE_UI, &MyFrame::OnUpdateUndo, this, wxID_UNDO);
    Bind(wxEVT_UPDATE_UI, &MyFrame::OnUpdateRedo, this, wxID_REDO);
 
    Bind(wxEVT_UPDATE_UI, &MyFrame::OnUpdateCut, this, wxID_CUT);
    Bind(wxEVT_UPDATE_UI, &MyFrame::OnUpdateCopy, this, wxID_COPY);
    Bind(wxEVT_UPDATE_UI, &MyFrame::OnUpdatePaste, this, wxID_PASTE);
cs

 

이벤트 핸들러인 OnPaste와 OnUpdatePaste을 구현한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
// 붙여넣기 기능.
void MyFrame::OnPaste(wxCommandEvent& event) {
    if (m_textControl->CanPaste()) {
        m_textControl->Paste();
    }
}
 
// 붙여넣기 기능 활성화.
void MyFrame::OnUpdatePaste(wxUpdateUIEvent& event)
{
    event.Enable(m_textControl->CanPaste());
}
 
cs

 

이렇게 하면, 마우스로 붙여넣기 메뉴를 사용해서 클립보드로 저장된걸 붙여넣을 수 있다.

Posted by JunkMam
,