Thinking Different






간단히 ms SAPI 내장 라이브러리를 이용해서 만든 스피치 영단어 프로그램입니다.

// 개개의 단어를 위해서 word 클래스를 선언

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
#pragma once
 
// Word Class
class Word
{
public:
    char word[50];
    char mean[50];
    char exk[256];
    char exe[256];
public:
    Word()
    {
        ZeroMemory(&word, sizeof(word));
        ZeroMemory(&mean, sizeof(mean));
        ZeroMemory(&exk, sizeof(exk));
        ZeroMemory(&exe, sizeof(exe));
    }
    void SetWord(char *s) { strcpy(word, s); }
    void SetMean(char *s) { strcpy(mean, s); }
    void SetExk(char *s) { strcpy(exk, s); }
    void SetExe(char *s) { strcpy(exe, s); }
    char* getWord() { return word; }
    char* getMean() { return mean; }
    char* getExk() { return exk; }
    char* getExe() { return exe; }
};


// api main 헤더, 기본적인 소스에 필요한 부분만 선언

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
#pragma once
 
#pragma warning(disable:4996)
 
#include "windows.h"
#include "resource.h"
#include "sapi.h"
#include "Word.h"
#include "stdio.h"
 
#define TRAY_NOTIFY (WM_APP+100)
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
DWORD WINAPI Thread(LPVOID p);
void openWordlist(HWND);
void closeWordlist();
 
HINSTANCE hInst;
HWND hWnd_Main;
HBITMAP bitmap, obitmap;
LPTSTR title = TEXT("word manager ver 0.1");
 
const int mX = 210;
const int mY = 230;
const int MAX_WORD = 1000;
 
Word *word[MAX_WORD];
static int cnt = 0;
ISpVoice * pVoice = NULL;
 
DWORD viewTime = 4000;
DWORD endTime = 7000;



// 기본 API 소스는 제외하고 중요 소스만 추가

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
void openWordlist(HWND hWnd)
{
    FILE *fp = fopen("eng_word.dat""r");
    if(!fp)
    {
        MessageBoxA(hWnd, "Can't Open File : eng_word.dat""Error", MB_OK);
        DestroyWindow(hWnd);
    }
 
    char buffer[1000]={0,};
    char *token = NULL;
 
    while(fgets(buffer, sizeof(buffer), fp))
    {
        word[cnt] = new Word;
        buffer[strlen(buffer)-1] = NULL;
        token = strtok(buffer, "\t");
        while(token != NULL)
        {
            word[cnt]->SetWord(token);        token  =  strtok(NULL, "\t");
            word[cnt]->SetMean(token);        token  =  strtok(NULL, "\t");
            if(token == NULL)
            {
                word[cnt]->SetExk("예제 없음");
                word[cnt]->SetExe("no exercise");
                cnt++;
                continue;
            }
            word[cnt]->SetExk(token);        token  =  strtok(NULL, "\t");
            word[cnt]->SetExe(token);        token  =  strtok(NULL, "\t");
            if(token != NULL)
            {
                cnt++;
                continue;
            }
            cnt++;
        }
    }
    fclose(fp);
}
void closeWordlist()
{
    for(int i = 0; i<cnt; i++)
    {
        delete word[i];
    }
    // SAPI Release
    if (pVoice)
    {
        pVoice->Release();
        pVoice = NULL;
    }
    CoUninitialize();
    ///////////////////
}
 
DWORD WINAPI Thread(LPVOID p)
{
    HDC hdc, mdc;
    HFONT font1, font2, ofont;
    char buf[256]={0,};
    wchar_t speak[256]={0,};
 
    hdc = GetDC(hWnd_Main);
 
    bitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));
    mdc = CreateCompatibleDC(hdc);
    obitmap = (HBITMAP)SelectObject(mdc, bitmap);
 
    SetTextAlign(hdc, TA_CENTER);
    SetBkMode(hdc, TRANSPARENT);
 
    if (FAILED(CoInitialize(NULL)))
        return -1;
 
    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
    if( SUCCEEDED( hr ) )
    {
        int i = 0;
        RECT rt;
        GetClientRect(hWnd_Main, &rt);        
 
        while(1)
        {
            if(i == cnt)
                i = 0;
            // 시작 Animation
            BitBlt(hdc, 0, 0, mX, mY, mdc, 0, 0, SRCCOPY);
            AnimateWindow(hWnd_Main, 50, AW_BLEND);
            BitBlt(hdc, 0, 0, mX, mY, mdc, 0, 0, SRCCOPY);
            font1 = CreateFont(18, 0,0,0,1000,0,0,0, HANGEUL_CHARSET,3,2,1,
                    VARIABLE_PITCH|FF_ROMAN, TEXT("돋움체"));
            font2 = CreateFont(14, 0,0,0,600,0,0,0, HANGEUL_CHARSET,3,2,1,
                    VARIABLE_PITCH|FF_ROMAN, TEXT("돋움체"));
            ofont = (HFONT)SelectObject(hdc, font1);
            sprintf(buf, "%s", word[i]->getWord());
            TextOutA(hdc, rt.right/2, 65, buf, strlen(buf));
            sprintf(buf, "%s", word[i]->getMean());
            TextOutA(hdc, rt.right/2, 95, buf, strlen(buf));
            SelectObject(hdc, ofont);
            DeleteObject(font1);
            ofont = (HFONT)SelectObject(hdc, font2);
            sprintf(buf, "%s", word[i]->getExe());
            TextOutA(hdc, rt.right/2, 135, buf, strlen(buf));
            sprintf(buf, "%s", word[i]->getExk());
            TextOutA(hdc, rt.right/2, 155, buf, strlen(buf));
            SelectObject(hdc, ofont);
            DeleteObject(font2);
            InvalidateRect(hWnd_Main, NULL, FALSE);
 
            sprintf(buf, "%s", word[i]->getWord());
            MultiByteToWideChar(CP_ACP, 0, buf, -1,  speak, sizeof(speak));
 
            pVoice->Speak(speak, 0, NULL);
            Sleep(viewTime);        // 실행동안 딜레이
 
            //종료 Animation
            AnimateWindow(hWnd_Main, 300, AW_HIDE | AW_BLEND);
            Sleep(endTime);        // 끝나고 딜레이
            i++;
        }
    } else
        return -1;
    SelectObject(mdc, obitmap);
    DeleteObject(bitmap);
    DeleteDC(mdc);
    ReleaseDC(hWnd_Main, hdc);
    return 0;
}



간단히 create에서 dat파일에서 wordlist를 입력받고 thread를 생성하여 구동되는 자동화 구조로 되어있습니다..    스레드 구조가 좀 많이 지저분하고, 복잡하네요... 저건 정리를 해야겠습니다.

소스는 따로 첨부하지 않으며 프로그램만 올립니다.

word manager 1.0.zip