시작 전 소개

뇌를 자극하는 윈도우즈 프로그래밍
1챕터 정리본 바로가기
2챕터 정리본 바로가기
3챕터 정리본 바로가기
4챕터 세션1 정리본
4챕터 세션 2 정리본
5챕터 세션 1-2-3 정리본

프로세스의 생성

프로세스 역시 이치에 맞게 구성되어야한다.
만약 우리가 MS워드 실행 중에 무언가 검색 할 일이 있어 익스플로어를 실행했다고 하면 과연 MS워드의 프로세스가 익스플로어를 실행했다라고 설명할 수 있을까

CreateProcess 함수

windows는 프로세스 생성을 돕기 위해 CreateProcess 함수를 제공해준다.
이때 이 함수를 호출하는 프로세스가 부모 프로세스, 생성된 프로세스가 자식 프로세스이다.

예제 코드 5-1

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
int _tmain(int argc, TCHAR* argv[])
{
	DWORD val1, val2;
	val1=_ttoi(argv[1]);//atoi와 _wtoi의 동시 지원
	val2=_ttoi(argv[2]);

	_tprintf(_T("%d + %d = %d \n"), val1, val2, val1+val2);

	_gettchar();
	return 0;
}

getchar과 getwhar
getchar 사용시 다음 입력이 주어지기 전까지는 대기 상태에 놓이게 된다.

예제코드 5-3

나는 우선 저자의 코드를 작성한 뒤 비주얼 스튜디오 상에 뜨는 오류를 수정하는 데에 집중하였다.
메모리 누수로 인한 오류가 뜨는 것을 핸들러를 닫는 과정을 통해 해결해주었다.
또한 6을 입력시 바로 종료를 시키는 것이 마음에 들지 않아서 6을 누르면 다시 한번 종료할 것인지 말 것인지 확인하기 위한 함수를 넣어주었다.

내가 수정한 소스코드

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

enum { DIV = 1, MUL, ADD, MIN, ELSE, EXIT };

DWORD ShowMenu();
void Divide(double, double);
void Multiple(double, double);
void Add(double, double);
void Min(double, double);
int t_option()
{
    int num3;
    _fputts(_T("Press 1: End, Press 2: continue \n"), stdout);
    _tscanf_s(_T("%d"), &num3);
    return num3;
}

int _tmain(int argc, TCHAR* argv[])
{
    STARTUPINFO si = { 0, };
    PROCESS_INFORMATION pi;
    si.cb = sizeof(si);

    TCHAR command[] = _T("calc.exe");
    SetCurrentDirectory(_T("C:\\WINDOWS\\system32"));

    DWORD sel;
    double num1, num2;
    while (true)
    {
        sel = ShowMenu();
        if (sel == EXIT) {
            int result=t_option();
            if (result == 1) {
                return 0;
            }
            else if (result == 2) {
                continue;
            }
            else {
                _fputts(_T("This is unexpected input"), stdout);
            }
        }

        if (sel != ELSE)
        {
            _fputts(_T("Input Num1 Num2: "), stdout);
            _tscanf_s(_T("%lf %lf"), &num1, &num2);
        }

        switch (sel)
        {
        case DIV:
            Divide(num1, num2);
            break;
        case MUL:
            Multiple(num1, num2);
            break;
        case ADD:
            Add(num1, num2);
            break;
        case MIN:
            Min(num1, num2);
            break;
        case ELSE:
            ZeroMemory(&pi, sizeof(pi));
            CreateProcess(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            break;
        }
    }

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return 0;
}

DWORD ShowMenu()
{
    DWORD sel;

    _fputts(_T("-----Menu----- \n"), stdout);
    _fputts(_T("num 1: Divide \n"), stdout);
    _fputts(_T("num 2: Multiple \n"), stdout);
    _fputts(_T("num 3: Add \n"), stdout);
    _fputts(_T("num 4: Minus \n"), stdout);
    _fputts(_T("num 5: Any other operations. \n"), stdout);
    _fputts(_T("num 6: Exit \n"), stdout);
    _fputts(_T("SELECTION >>"), stdout);
    _tscanf_s(_T("%d"), &sel);
    return sel;
}

void Divide(double a, double b)
{
    _tprintf(_T("%f/%f=%f \n\n"), a, b, a / b);
}

void Multiple(double a, double b)
{
    _tprintf(_T("%f*%f=%f \n\n"), a, b, a * b);
}

void Add(double a, double b)
{
    _tprintf(_T("%f+%f=%f \n\n"), a, b, a + b);
}

void Min(double a, double b)
{
    _tprintf(_T("%f-%f=%f \n\n"), a, b, a - b);
}

아마도 내가 작성한 코드를 읽으면 바로 이해 가능한 직관적 코드라고 생각한다.
세션 6에 있는 예제는 앞에서 보여준 예제와 내용들의 연장선에서 MSDN문서만 읽고와도 해결 가능한 부분이어서 따로 첨부하지는 않았다.

댓글남기기