1日でわかるMFC (GARAさんのページ)
BACK  
 Sample_F スレッドを持つWindowsプログラム

Sample_F1.c はSDKのプログラムです。
Sample_F2.cpp はメインウィンドウをクラス化しています。
Sample_F3.cpp はスレッド関数をクラスのメンバにしています。
Sample_F4.cpp は AfxBeginThread() を使用してスレッドを作成しています。

プログラム概要
・ スレッドを3つ作成して、各スレッドが現在時刻をメインウィンドウに表示します。



共通ファイル
1)Sample_F.h
#define MENU_NAME   NULL        // メニュー名
#define WIN_W       300         // Window の幅
#define WIN_H       160         // Window の高
#define WIN_X       100         // Window の水平座標
#define WIN_Y       50          // Window の垂直座標

 Sample_F1.c SDKのプログラム (緑色の部分は各 .c ファイル共通です)
TOP  
/** Sample_F1.c:スレッドを持つWindowsプログラム (by GARA) **/

#include <windows.h>
#include "Sample_F.h"

/* Define */
#define CLASS_NAME  "Sample_F1Class"    // クラス名
#define WIN_TITLE   "Sample_F1"         // タイトル

/* Global */
// CRITICAL_SECTION ctirical;
HWND    hWndMain;
int     gThreadFlg;
HANDLE  hThrd1, hThrd2, hThrd3;
char    StartMsg[80];

/* Proto Type */
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL InitApplication(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
void Thread_1(void);
void Thread_2(void);
void Thread_3(void);
void DispSub(int, char *);

/* WinMain */
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    Sample_A1.c と同じ
}

/* ウィンドウクラスの登録 */
BOOL InitApplication(HINSTANCE hInstance)
{
    Sample_A1.c と同じ
}

/* ウィンドウの作成と表示 */
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    Sample_A1.c と同じ
}

/* ウィンドウプロシージャ */
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    DWORD       ThrdId;
    HDC         hDC;
    PAINTSTRUCT ps;
    SYSTEMTIME  st;

    switch(uMsg) {
        case WM_CREATE:
            hWndMain = hWnd;
//          InitializeCriticalSection(&ctirical);
            gThreadFlg = 1;
            hThrd1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_1, (LPVOID)NULL, 0, &ThrdId);
            hThrd2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_2, (LPVOID)NULL, 0, &ThrdId);
            hThrd3 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_3, (LPVOID)NULL, 0, &ThrdId);
            GetLocalTime(&st);
            wsprintf(StartMsg, "Start Time : %02d/%02d %02d:%02d:%02d",
                                                st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
            break;
        case WM_PAINT:
            BeginPaint(hWnd, &ps);
            hDC = ps.hdc;
            TextOut(hDC, 10, 10, "SDK -> MFC", 10);
            TextOut(hDC, 10, 30, StartMsg, lstrlen(StartMsg));
            EndPaint(hWnd, &ps);
            break;
        case WM_CLOSE:
            gThreadFlg = 0;         // スレッド終了指示
            Sleep(1000);            // スレッド終了のため1秒待つ(スレッドは1秒以内に終わるはず)
            CloseHandle(hThrd1);    // CreateThread() でスレッドを作成したときは CloseHandle() が必要
            CloseHandle(hThrd2);
            CloseHandle(hThrd3);
            DestroyWindow(hWnd);
            break;
        case WM_DESTROY:
//          DeleteCriticalSection(&ctirical);
            PostQuitMessage(0);
            break;
        default:
            return(DefWindowProc(hWnd, uMsg, wParam, lParam));
    }

    return 0;
}

/* スレッド1 */
void Thread_1(void)
{
    SYSTEMTIME  st;
    char        WkBuf[80];

    while(gThreadFlg) {
        GetLocalTime(&st);
        wsprintf(WkBuf, "スレッド1:%02d/%02d %02d:%02d:%02d",
                                    st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        DispSub(1, WkBuf);
        Sleep(100);
    }
    ExitThread(1);              // スレッド終了
}

/* スレッド2 */
void Thread_2(void)
{
    SYSTEMTIME  st;
    char        WkBuf[80];

    while(gThreadFlg) {
        GetLocalTime(&st);
        wsprintf(WkBuf, "スレッド2:%02d/%02d %02d:%02d:%02d",
                                    st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        DispSub(2, WkBuf);
        Sleep(150);
    }
    ExitThread(2);              // スレッド終了
}

/* スレッド3 */
void Thread_3(void)
{
    SYSTEMTIME  st;
    char        WkBuf[80];

    while(gThreadFlg) {
        GetLocalTime(&st);
        wsprintf(WkBuf, "スレッド3:%02d/%02d %02d:%02d:%02d",
                                    st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        DispSub(3, WkBuf);
        Sleep(200);
    }
    ExitThread(3);              // スレッド終了
}

/* スレッドから呼ばれる関数 */
void DispSub(int Id, char *Buf)
{
    HDC     hDC;
    int     y;

//  EnterCriticalSection(&ctirical);            // スレッド間の排他が必要なときは生かす
    y = 35 + 20 * Id;
    hDC = GetDC(hWndMain);
    TextOut(hDC, 40, y, Buf, lstrlen(Buf));     // lstrlen() はスレッドセーフ
    ReleaseDC(hWndMain, hDC);
//  LeaveCriticalSection(&ctirical);
    return;
}

 Sample_F2.cpp メインウィンドウをクラス化 (緑色の部分は各 .cpp ファイル共通です)
TOP  
/** Sample_F2.cpp:スレッドを持つWindowsプログラム (by GARA) **/

#include <afxwin.h>
#include "Sample_F.h"

/* Define */
#define CLASS_NAME  "Sample_F2Class"    // クラス名
#define WIN_TITLE   "Sample_F2"         // タイトル

/* Global */
// CRITICAL_SECTION ctirical;
HWND    hWndMain;
int     gThreadFlg;
HANDLE  hThrd1, hThrd2, hThrd3;
char    StartMsg[80];

/* Proto Type */
void Thread_1(void);
void Thread_2(void);
void Thread_3(void);
void DispSub(int, char *);

/* ウィンドウクラスの宣言 */
class CMainFrame : public CFrameWnd     // ウィンドウクラス CWnd -> CFrameWnd
{
public:
    // コンストラクタ
    CMainFrame();
    // メンバ関数
    virtual BOOL PreCreateWindow(CREATESTRUCT&);
    // メッセージハンドラ
    afx_msg int  OnCreate(LPCREATESTRUCT);      // WM_CREATE に対応
    afx_msg void OnPaint();                     // WM_PAINT に対応
    afx_msg void OnClose();                     // WM_CLOSE に対応
    afx_msg void OnDestroy();                   // WM_DESTROY に対応
    DECLARE_MESSAGE_MAP()
};

/* メッセージマップの定義 */
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)    // 第1引数:メッセージマップを所有するクラスの名前、第2引数:基本クラス名
    ON_WM_CREATE()
    ON_WM_PAINT()
    ON_WM_CLOSE()
    ON_WM_DESTROY()
END_MESSAGE_MAP()

/* アプリケーションクラスの宣言 */
class CMyApp : public CWinApp
{
public:
    virtual BOOL InitInstance();        // インスタンスを初期化する関数
};

/* ウィンドウクラスのメンバ */
// コンストラクタ
CMainFrame::CMainFrame()                // コンストラクタ
{
    Create(NULL, "");                   // ウィンドウの作成。第1引数:クラス名、第2引数:ウィンドウ名
}

// メンバ関数
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)  // PreCreateWindow() のオーバーライド
{
    Sample_A2.cpp と同じ 
}

// メッセージハンドラ
int CMainFrame::OnCreate(LPCREATESTRUCT cs)
{
    DWORD       ThrdId;
    SYSTEMTIME  st;

    hWndMain = m_hWnd;
//  InitializeCriticalSection(&ctirical);
    // スレッドの作成
    gThreadFlg = 1;
    hThrd1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_1, (LPVOID)NULL, 0, &ThrdId);
    hThrd2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_2, (LPVOID)NULL, 0, &ThrdId);
    hThrd3 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_3, (LPVOID)NULL, 0, &ThrdId);
    GetLocalTime(&st);
    wsprintf(StartMsg, "Start Time : %02d/%02d %02d:%02d:%02d",
                                        st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    return 0;
}

void CMainFrame::OnPaint()          // OnPaint() のオーバーライド
{
    HWND        hWnd;
    HDC         hDC;
    PAINTSTRUCT ps;

    hWnd = m_hWnd;
    ::BeginPaint(hWnd, &ps);
    hDC = ps.hdc;
    TextOut(hDC, 10, 10, "SDK -> MFC", 10);
    TextOut(hDC, 10, 30, StartMsg, lstrlen(StartMsg));
    ::EndPaint(hWnd, &ps);
    return;
}

void CMainFrame::OnClose()          // OnClose() のオーバーライド
{
    gThreadFlg = 0;             // スレッド終了指示
    Sleep(1000);                // スレッド終了のため1秒待つ(スレッドは1秒以内に終わるはず)
    CloseHandle(hThrd1);        // CreateThread() でスレッドを作成したときは CloseHandle() が必要
    CloseHandle(hThrd2);
    CloseHandle(hThrd3);
    ::DestroyWindow(m_hWnd);
    return;
}

void CMainFrame::OnDestroy()        // OnDestroy() のオーバーライド
{
//  DeleteCriticalSection(&ctirical);
    PostQuitMessage(0);
    return;
}

/* スレッド1 */
void Thread_1(void)
{
    SYSTEMTIME  st;
    char        WkBuf[80];

    while(gThreadFlg) {
        GetLocalTime(&st);
        wsprintf(WkBuf, "スレッド1:%02d/%02d %02d:%02d:%02d",
                                    st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        DispSub(1, WkBuf);
        Sleep(100);
    }
    ExitThread(1);              // スレッド終了
}

/* スレッド2 */
void Thread_2(void)
{
    SYSTEMTIME  st;
    char        WkBuf[80];

    while(gThreadFlg) {
        GetLocalTime(&st);
        wsprintf(WkBuf, "スレッド2:%02d/%02d %02d:%02d:%02d",
                                    st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        DispSub(2, WkBuf);
        Sleep(150);
    }
    ExitThread(2);              // スレッド終了
}

/* スレッド3 */
void Thread_3(void)
{
    SYSTEMTIME  st;
    char        WkBuf[80];

    while(gThreadFlg) {
        GetLocalTime(&st);
        wsprintf(WkBuf, "スレッド3:%02d/%02d %02d:%02d:%02d",
                                    st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        DispSub(3, WkBuf);
        Sleep(200);
    }
    ExitThread(3);              // スレッド終了
}

/* スレッドから呼ばれる関数 */
void DispSub(int Id, char *Buf)
{
    HDC     hDC;
    int     y;

//  EnterCriticalSection(&ctirical);            // スレッド間の排他が必要なときは生かす
    y = 35 + 20 * Id;
    hDC = GetDC(hWndMain);
    TextOut(hDC, 40, y, Buf, lstrlen(Buf));     // lstrlen() はスレッドセーフ
    ReleaseDC(hWndMain, hDC);
//  LeaveCriticalSection(&ctirical);
    return;
}

/* アプリケーションクラスのメンバ */
// メンバ関数
BOOL CMyApp::InitInstance()         // InitInstance() のオーバーライド
{
    m_pMainWnd = new CMainFrame();          // メインウィンドウの作成
    m_pMainWnd->ShowWindow(m_nCmdShow);
    m_pMainWnd->UpdateWindow();

    return TRUE;
}


/* アプリケーションの生成(実行)*/

CMyApp MyApp;


 Sample_F3.cpp スレッド関数をクラスのメンバ化 (緑色の部分は各 .cpp ファイル共通です)
TOP  
/** Sample_F3.cpp:スレッドを持つWindowsプログラム (by GARA) **/

#include <afxwin.h>
#include "Sample_F.h"

/* Define */
#define CLASS_NAME  "Sample_F3Class"    // クラス名
#define WIN_TITLE   "Sample_F3"         // タイトル

/* Global */
HWND    hWndMain;
// CRITICAL_SECTION ctirical;
int     gThreadFlg;
HANDLE  hThrd1, hThrd2, hThrd3;
char    StartMsg[80];

/* ウィンドウクラスの宣言 */
class CMainFrame : public CFrameWnd     // ウィンドウクラス CWnd -> CFrameWnd
{
public:
    // コンストラクタ
    CMainFrame();
    // メンバ関数
    virtual BOOL PreCreateWindow(CREATESTRUCT&);
//  void Thread_1(void);                // <- compile error C2440
    static void Thread_1(void);
    static void Thread_2(void);
    static void Thread_3(void);
    static void DispSub(int, char *);
//  void DispSub(int, char *);          // <- compile error C2352
    // メッセージハンドラ
    afx_msg int  OnCreate(LPCREATESTRUCT);      // WM_CREATE に対応
    afx_msg void OnPaint();                     // WM_PAINT に対応
    afx_msg void OnClose();                     // WM_CLOSE に対応
    afx_msg void OnDestroy();                   // WM_DESTROY に対応
    DECLARE_MESSAGE_MAP()
};

/* メッセージマップの定義 */
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)    // 第1引数:メッセージマップを所有するクラスの名前、第2引数:基本クラス名
    ON_WM_CREATE()
    ON_WM_PAINT()
    ON_WM_CLOSE()
    ON_WM_DESTROY()
END_MESSAGE_MAP()

/* アプリケーションクラスの宣言 */
class CMyApp : public CWinApp
{
public:
    virtual BOOL InitInstance();        // インスタンスを初期化する関数
};

/* ウィンドウクラスのメンバ */
// コンストラクタ
CMainFrame::CMainFrame()                // コンストラクタ
{
    Create(NULL, "");                   // ウィンドウの作成。第1引数:クラス名、第2引数:ウィンドウ名
}

// メンバ関数
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)  // PreCreateWindow() のオーバーライド
{
    Sample_A2.cpp と同じ 
}

// メッセージハンドラ
int CMainFrame::OnCreate(LPCREATESTRUCT cs)
{
    DWORD       ThrdId;
    SYSTEMTIME  st;

    hWndMain = m_hWnd;
//  InitializeCriticalSection(&ctirical);
    // スレッドの作成
    gThreadFlg = 1;
    hThrd1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_1, (LPVOID)NULL, 0, &ThrdId);
    hThrd2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_2, (LPVOID)NULL, 0, &ThrdId);
    hThrd3 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_3, (LPVOID)NULL, 0, &ThrdId);
    GetLocalTime(&st);
    wsprintf(StartMsg, "Start Time : %02d/%02d %02d:%02d:%02d",
                                        st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    return 0;
}

void CMainFrame::OnPaint()          // OnPaint() のオーバーライド
{
    HWND        hWnd;
    HDC         hDC;
    PAINTSTRUCT ps;

    hWnd = m_hWnd;
    ::BeginPaint(hWnd, &ps);
    hDC = ps.hdc;
    TextOut(hDC, 10, 10, "SDK -> MFC", 10);
    TextOut(hDC, 10, 30, StartMsg, lstrlen(StartMsg));
    ::EndPaint(hWnd, &ps);
    return;
}

void CMainFrame::OnClose()          // OnClose() のオーバーライド
{
    gThreadFlg = 0;             // スレッド終了指示
    Sleep(1000);                // スレッド終了のため1秒待つ(スレッドは1秒以内に終わるはず)
    CloseHandle(hThrd1);        // CreateThread() でスレッドを作成したときは CloseHandle() が必要
    CloseHandle(hThrd2);
    CloseHandle(hThrd3);
    ::DestroyWindow(m_hWnd);
    return;
}

void CMainFrame::OnDestroy()        // OnDestroy() のオーバーライド
{
//  DeleteCriticalSection(&ctirical);
    PostQuitMessage(0);
    return;
}

// スレッド1
void CMainFrame::Thread_1(void)
{
    SYSTEMTIME  st;
    char        WkBuf[80];

    while(gThreadFlg) {
        GetLocalTime(&st);
        wsprintf(WkBuf, "スレッド1:%02d/%02d %02d:%02d:%02d",
                                    st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        DispSub(1, WkBuf);
        Sleep(100);
    }
    ExitThread(1);              // スレッド終了
}

// スレッド2
void CMainFrame::Thread_2(void)
{
    SYSTEMTIME  st;
    char        WkBuf[80];

    while(gThreadFlg) {
        GetLocalTime(&st);
        wsprintf(WkBuf, "スレッド2:%02d/%02d %02d:%02d:%02d",
                                    st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        DispSub(2, WkBuf);
        Sleep(150);
    }
    ExitThread(2);              // スレッド終了
}

// スレッド3
void CMainFrame::Thread_3(void)
{
    SYSTEMTIME  st;
    char        WkBuf[80];

    while(gThreadFlg) {
        GetLocalTime(&st);
        wsprintf(WkBuf, "スレッド3:%02d/%02d %02d:%02d:%02d",
                                    st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        DispSub(3, WkBuf);
        Sleep(200);
    }
    ExitThread(3);              // スレッド終了
}

// スレッドから呼ばれる関数
void CMainFrame::DispSub(int Id, char *Buf)
{
    HDC     hDC;
    int     y;

//  EnterCriticalSection(&ctirical);            // スレッド間の排他が必要なときは生かす
    y = 35 + 20 * Id;
//  hDC = ::GetDC(m_hWnd);                      // m_hWnd は参照できない(C2597)
    hDC = ::GetDC(hWndMain);
    TextOut(hDC, 40, y, Buf, lstrlen(Buf));     // lstrlen() はスレッドセーフ
//  ::ReleaseDC(m_hWnd, hDC);
    ::ReleaseDC(hWndMain, hDC);
//  LeaveCriticalSection(&ctirical);
    return;
}

/* アプリケーションクラスのメンバ */
// メンバ関数
BOOL CMyApp::InitInstance()         // InitInstance() のオーバーライド
{
    m_pMainWnd = new CMainFrame();          // メインウィンドウの作成
    m_pMainWnd->ShowWindow(m_nCmdShow);
    m_pMainWnd->UpdateWindow();

    return TRUE;
}


/* アプリケーションの生成(実行)*/

CMyApp MyApp;


 Sample_F4.cpp AfxBeginThread() でスレッドを作成 (緑色の部分は各 .cpp ファイル共通です)
TOP  
/** Sample_F4.cpp:スレッドを持つWindowsプログラム (AfxBeginThread Version) (by GARA) **/

#include <afxwin.h>
#include "Sample_F.h"

/* Define */
#define CLASS_NAME  "Sample_F4Class"    // クラス名
#define WIN_TITLE   "Sample_F4"         // タイトル

/* Global */
// CRITICAL_SECTION ctirical;
HWND    hWndMain;
int     gThreadFlg;
char    StartMsg[80];

/* ウィンドウクラスの宣言 */
class CMainFrame : public CFrameWnd     // ウィンドウクラス CWnd -> CFrameWnd
{
public:
    // コンストラクタ
    CMainFrame();
    // メンバ関数
    virtual BOOL PreCreateWindow(CREATESTRUCT&);
    static UINT Thread_1(void *);               // スレッド関数の型と引数はこれでないとコンパイルエラー(C2665)
    static UINT Thread_2(void *);
    static UINT Thread_3(void *);
    static void DispSub(int, char *);
    // メッセージハンドラ
    afx_msg int  OnCreate(LPCREATESTRUCT);      // WM_CREATE に対応
    afx_msg void OnPaint();                     // WM_PAINT に対応
    afx_msg void OnClose();                     // WM_CLOSE に対応
    afx_msg void OnDestroy();                   // WM_DESTROY に対応
    DECLARE_MESSAGE_MAP()
};

/* メッセージマップの定義 */
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)    // 第1引数:メッセージマップを所有するクラスの名前、第2引数:基本クラス名
    ON_WM_CREATE()
    ON_WM_PAINT()
    ON_WM_CLOSE()
    ON_WM_DESTROY()
END_MESSAGE_MAP()

/* アプリケーションクラスの宣言 */
class CMyApp : public CWinApp
{
public:
    virtual BOOL InitInstance();        // インスタンスを初期化する関数
};

/* ウィンドウクラスのメンバ */
// コンストラクタ
CMainFrame::CMainFrame()                // コンストラクタ
{
    Create(NULL, "");                   // ウィンドウの作成。第1引数:クラス名、第2引数:ウィンドウ名
}

// メンバ関数
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)  // PreCreateWindow() のオーバーライド
{
    Sample_A2.cpp と同じ 
}

// メッセージハンドラ
int CMainFrame::OnCreate(LPCREATESTRUCT cs)
{
    CWinThread  *pWinThrd1, *pWinThrd2, *pWinThrd3;
    SYSTEMTIME  st;

    hWndMain = m_hWnd;
//  InitializeCriticalSection(&ctirical);
    // スレッドの作成
    gThreadFlg = 1;
    pWinThrd1 = AfxBeginThread(Thread_1, (LPVOID)NULL, THREAD_PRIORITY_NORMAL);
    pWinThrd2 = AfxBeginThread(Thread_2, (LPVOID)NULL, THREAD_PRIORITY_NORMAL);
    pWinThrd3 = AfxBeginThread(Thread_3, (LPVOID)NULL, THREAD_PRIORITY_NORMAL);
    GetLocalTime(&st);
    wsprintf(StartMsg, "Start Time : %02d/%02d %02d:%02d:%02d",
                                        st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    return 0;
}

void CMainFrame::OnPaint()          // OnPaint() のオーバーライド
{
    HWND        hWnd;
    HDC         hDC;
    PAINTSTRUCT ps;

    hWnd = m_hWnd;
    ::BeginPaint(hWnd, &ps);
    hDC = ps.hdc;
    TextOut(hDC, 10, 10, "SDK -> MFC", 10);
    TextOut(hDC, 10, 30, StartMsg, lstrlen(StartMsg));
    ::EndPaint(hWnd, &ps);
    return;
}

void CMainFrame::OnClose()          // OnClose() のオーバーライド
{
    gThreadFlg = 0;     // スレッド終了指示
    Sleep(1000);        // スレッド終了のため1秒待つ
    ::DestroyWindow(m_hWnd);
    return;
}

void CMainFrame::OnDestroy()        // OnDestroy() のオーバーライド
{
//  DeleteCriticalSection(&ctirical);
    PostQuitMessage(0);
    return;
}

/* スレッド1 */
UINT CMainFrame::Thread_1(void *Param)
{
    SYSTEMTIME  st;
    char        WkBuf[80];

    while(gThreadFlg) {
        GetLocalTime(&st);
        sprintf(WkBuf, "スレッド1:%02d/%02d %02d:%02d:%02d",      // sprintf() はCランタイムライブラリ
                                st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        DispSub(1, WkBuf);
        Sleep(100);
    }
    AfxEndThread(1);            // スレッド終了  <- スレッドの終了コードは return の値でなく、こちらの値が戻る
    return 0;                   // return がないとコンパイルエラー(C4716)
}

/* スレッド2 */
UINT CMainFrame::Thread_2(void *Param)
{
    SYSTEMTIME  st;
    char        WkBuf[80];

    while(gThreadFlg) {
        GetLocalTime(&st);
        sprintf(WkBuf, "スレッド2:%02d/%02d %02d:%02d:%02d",      // sprintf() はCランタイムライブラリ
                                st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        DispSub(2, WkBuf);
        Sleep(150);
    }
    AfxEndThread(2);            // スレッド終了  <- スレッドの終了コードは return の値でなく、こちらの値が戻る
    return 0;                   // return がないとコンパイルエラー(C4716)
}

/* スレッド3 */
UINT CMainFrame::Thread_3(void *Param)
{
    SYSTEMTIME  st;
    char        WkBuf[80];

    while(gThreadFlg) {
        GetLocalTime(&st);
        sprintf(WkBuf, "スレッド3:%02d/%02d %02d:%02d:%02d",      // sprintf() はCランタイムライブラリ
                                st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        DispSub(3, WkBuf);
        Sleep(200);
    }
    AfxEndThread(3);            // スレッド終了  <- スレッドの終了コードは return の値でなく、こちらの値が戻る
    return 0;                   // return がないとコンパイルエラー(C4716)
}

/* スレッドから呼ばれる関数 */
void CMainFrame::DispSub(int Id, char *Buf)
{
    HDC     hDC;
    int     y;

//  EnterCriticalSection(&ctirical);            // スレッド間の排他が必要なときは生かす
    y = 35 + 20 * Id;
    hDC = ::GetDC(hWndMain);
    TextOut(hDC, 40, y, Buf, strlen(Buf));      // strlen() はCランタイムライブラリ
    ::ReleaseDC(hWndMain, hDC);
//  LeaveCriticalSection(&ctirical);
    return;
}

/* アプリケーションクラスのメンバ */
// メンバ関数
BOOL CMyApp::InitInstance()         // InitInstance() のオーバーライド
{
    m_pMainWnd = new CMainFrame();          // メインウィンドウの作成
    m_pMainWnd->ShowWindow(m_nCmdShow);
    m_pMainWnd->UpdateWindow();

    return TRUE;
}


/* アプリケーションの生成(実行)*/

CMyApp MyApp;



BACK  TOP