오다기리 박의 알고리즘 노트

[핵심 API로 배우는 윈도우프로그래밍(강경우, 한빛아카데미)] 8장 5번 풀이 본문

WIN32 API

[핵심 API로 배우는 윈도우프로그래밍(강경우, 한빛아카데미)] 8장 5번 풀이

오다기리 박 2018. 1. 9. 17:54
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#include <Windows.h>
#include<tchar.h>
#include<string.h>
#include"resource.h"
#include<winres.h>
//#pragma comment(linker,"/entry:WinMainCRTStartup /subsystem:console")
LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
void ReadFromFile(int WndIndex, TCHAR filename[]);
void SaveFromFile(HWND hwnd, TCHAR filename[]);
 
int SelectWnd;
int WndCount;
RECT rt[100];
HWND hwndChild[100];        //각 자식윈도우의 핸들
static HWND hEdit[100];
TCHAR WinBuff[100][1000];    //불러온 파일내용을 읽어들여 저장할 버퍼공간
HINSTANCE hInst;
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
    HWND hwnd;
    MSG msg;
    WNDCLASS WndClass;
 
    hInst = hInstance;
    WndClass.style = CS_HREDRAW | CS_VREDRAW;
    WndClass.lpfnWndProc = FrameWndProc;
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hInstance = hInstance;
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
    WndClass.lpszClassName = _T("Window Class Name");
 
    RegisterClass(&WndClass);
 
    WndClass.lpfnWndProc = ChildWndProc;
    WndClass.lpszMenuName = NULL;
    WndClass.lpszClassName = _T("Child Window Class Name");
 
    RegisterClass(&WndClass);
 
    hwnd = CreateWindow(                    //프레임 윈도우 생성
        _T("Window Class Name"),
        _T("박정호"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);
 
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
 
    while (GetMessage(&msg, NULL00))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}
#define IDC_EDIT1 100
LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    static HWND hwndClient;
    CLIENTCREATESTRUCT clientcreate;
    MDICREATESTRUCT mdicreate;
    static TCHAR filepath[1000], folder[100], filename[100];
    TCHAR filter[] = _T("텍스트 파일 (*.txt)\0*.txt\0모든 파일 (*.*)\0*.*\0");
    OPENFILENAME OFN, SFN;
    LPTSTR pStr;
 
    switch (iMsg)
    {
    case WM_CREATE:
        clientcreate.hWindowMenu = GetSubMenu(GetMenu(hwnd), 0);
        clientcreate.idFirstChild = 100;
        hwndClient = CreateWindow(            //클라이언트 윈도우 생성
            _T("MDICLIENT"), NULL, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
            0000,
            hwnd, NULL, hInst, (LPSTR)&clientcreate);
        ShowWindow(hwndClient, SW_SHOW);    //프레임 윈도우에 클라이언트 윈도우가 나타남
        return 0;
        break;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case ID_FILEOPEN:
            memset(&OFN, 0sizeof(OPENFILENAME));
            OFN.lStructSize = sizeof(OPENFILENAME);
            OFN.hwndOwner = hwnd;
            OFN.lpstrFile = filepath;        //사용자가 선택한 파일경로
            OFN.nMaxFile = 1000;            //파일경로의 최대크기
 
            OFN.lpstrFileTitle = filename;    //사용자가 선택한 파일제목
            OFN.nMaxFileTitle = 100;        //파일제목의 최대크기
 
            OFN.lpstrFilter = filter;
            OFN.Flags = OFN_EXPLORER| OFN_ALLOWMULTISELECT;
            OFN.lpstrInitialDir = _T(".");
            GetOpenFileName(&OFN);            //OFN구조체의 내용을 기반으로 [열기]대화상자를 초기화하고,
                                            //사용자가 선택한 파일의 정보가 저장되고 파일선택시 1반환
            pStr = filepath;
            if (!*pStr) break;                //파일선택이 안됐다면끝
            _tcscpy_s(folder, pStr);        //파일 경로를 folder에 저장
            pStr = pStr + _tcslen(pStr) + 1;//pStr은 첫번째 파일이름을 가리킨다
            if (!*pStr)                        //파일을 하나만 선택했다면
            {
                WndCount++;
                ReadFromFile(WndCount, filepath);//파일로부터 텍스트를 읽어들인다
                mdicreate.szClass = _T("Child Window Class Name");
                mdicreate.szTitle = filename;
                mdicreate.hOwner = hInst;
                mdicreate.x = CW_USEDEFAULT;
                mdicreate.y = CW_USEDEFAULT;
                mdicreate.cx = CW_USEDEFAULT;
                mdicreate.cy = CW_USEDEFAULT;
                mdicreate.style = 0;
                mdicreate.lParam = 0;
                hwndChild[WndCount] = (HWND)SendMessage(hwndClient, WM_MDICREATE, 0, (LPARAM)(LPMDICREATESTRUCT)&mdicreate);
                //클라이언트 윈도우에게 mdicreate의 내용을 가지고 자식 윈도우를 만들라는 메시지
                hEdit[WndCount] = CreateWindow(
                    _T("edit"), NULL, WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |    //에디트 컨트롤 생성
                    ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE, 0100,
                    rt[WndCount].right, rt[WndCount].bottom, hwndChild[WndCount], (HMENU)IDC_EDIT1, hInst, NULL);
                GetClientRect(hwndChild[WndCount], &rt[WndCount]);
                MoveWindow(hEdit[SelectWnd], 00, rt[SelectWnd].right, rt[SelectWnd].bottom, TRUE);
                SetWindowText(hEdit[WndCount], WinBuff[WndCount]);
                return 0;
            }
 
            while (*pStr)
            {
                _tcscpy_s(filename, pStr);
                pStr = pStr + _tcslen(pStr) + 1;
                WndCount++;
                ReadFromFile(WndCount, filename);//파일로부터 텍스트를 읽어들인다
                mdicreate.szClass = _T("Child Window Class Name");
                mdicreate.szTitle = filename;
                mdicreate.hOwner = hInst;
                mdicreate.x = CW_USEDEFAULT;
                mdicreate.y = CW_USEDEFAULT;
                mdicreate.cx = CW_USEDEFAULT;
                mdicreate.cy = CW_USEDEFAULT;
                mdicreate.style = 0;
                mdicreate.lParam = 0;
                hwndChild[WndCount] = (HWND)SendMessage(hwndClient, WM_MDICREATE, 0, (LPARAM)(LPMDICREATESTRUCT)&mdicreate);
                //클라이언트 윈도우에게 mdicreate의 내용을 가지고 자식 윈도우를 만들라는 메시지
                hEdit[WndCount] = CreateWindow(
                    _T("edit"), NULL, WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |    //에디트 컨트롤 생성
                    ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE, 0100,
                    rt[WndCount].right, rt[WndCount].bottom, hwndChild[WndCount], (HMENU)IDC_EDIT1, hInst, NULL);
                GetClientRect(hwndChild[WndCount], &rt[WndCount]);
                MoveWindow(hEdit[SelectWnd], 00, rt[SelectWnd].right, rt[SelectWnd].bottom, TRUE);
                SetWindowText(hEdit[WndCount], WinBuff[WndCount]);
            }
            return 0;
        case ID_FILESAVE:
            memset(&SFN, 0sizeof(OPENFILENAME));
            SFN.lStructSize = sizeof(OPENFILENAME);
            SFN.hwndOwner = hwnd;
            SFN.lpstrFilter = filter;
            SFN.lpstrFile = filepath;
            SFN.nMaxFile = 1000;
            OFN.lpstrFileTitle = filename;
            OFN.nMaxFileTitle = 100;
            SFN.lpstrInitialDir = _T(".");
            GetSaveFileName(&SFN);
            SaveFromFile(hEdit[SelectWnd], filepath);
            break;
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefFrameProc(hwnd, hwndClient, iMsg, wParam, lParam);
}
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
 
    for (int i = 1; i <= WndCount; i++)
    {
        if (hwnd == hwndChild[i])
        {
            SelectWnd = i;
            break;
        }
    }
 
    switch (iMsg)
    {
    case WM_CREATE:
        //SetWindowText(hEdit[SelectWnd], WinBuff[SelectWnd]);
        break;
    case WM_PAINT:
        break;
    case WM_SIZE:
        GetClientRect(hwnd, &rt[SelectWnd]);
        MoveWindow(hEdit[SelectWnd], 00, rt[SelectWnd].right, rt[SelectWnd].bottom, TRUE);
        break;
    case WM_DESTROY:
        break;
    }
    return DefMDIChildProc(hwnd, iMsg, wParam, lParam);
}
void ReadFromFile(int WndIndex, TCHAR filename[])
{
    HANDLE hFile;
    DWORD size = 1000;
    hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 00);
    ReadFile(hFile, WinBuff[WndIndex], size * sizeof(TCHAR), &sizeNULL);
    WinBuff[WndIndex][size= NULL;
    CloseHandle(hFile);
}
void SaveFromFile(HWND hwnd, TCHAR filename[])
{
    HANDLE hFile;
    LPTSTR buffer;
    int size;
 
    hFile = CreateFile(filename, GENERIC_WRITE, 00,                        //1.파일 생성(파일에 텍스트를 저장해야하기때문에 GENERIC_WRITE사용
        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
 
    size = GetWindowTextLength(hwnd);                                        //버퍼 크기 결정위해 에디트컨트롤 텍스트의 길이 얻어옴
    buffer = new TCHAR[size + 1];
    memset(buffer, 0, (size + 1* sizeof(TCHAR));
    size = GetWindowText(hwnd, (LPTSTR)buffer, size + 1);                    //에디트 컨트롤의 텍스트->버퍼 읽어들이기
    buffer[size= NULL;
    WriteFile(hFile, buffer, size * sizeof(TCHAR), (LPDWORD)&sizeNULL);    //2.파일 쓰기(버퍼->파일 저장)
    free(buffer);
    CloseHandle(hFile);
}
cs