2013.07.09 17:07



BroadcastReceiver.cpp


BroadcastSender.cpp


'Computer > CPP' 카테고리의 다른 글

함수 포인터 및 클래스 멤버함수의 함수포인터화  (0) 2015.09.02
멀티바이트와 유니코드  (0) 2013.07.27
BroadCasting 참고 코드  (0) 2013.07.09
Virtual Key Code  (0) 2013.07.06
키보드 이벤트 처리하기  (0) 2013.07.05
Visual Studio 2012 단축키  (0) 2013.07.05


Posted by injunech
2013.07.09 12:40


 

CWinThread*     pThread = NULL;

static volatile bool  isThreadRunning;

 

//////////////////////////////////////////////////////////////////////////

//

//              AfxbeginThread에 등록되는 함수.

//              반드시 static (전역)함수여야 한다.

//

//////////////////////////////////////////////////////////////////////////

UINT MyThread(LPVOID lpParam)

{

        MyClass* pClass = (MyClass*) lpParam;

        int iReturn     = pClass->ThreadFunction();

        return 0L;

}

 

 

//////////////////////////////////////////////////////////////////////////

//

//              Thread 생성 함수

//

//////////////////////////////////////////////////////////////////////////

void MyClass::CreateThread(UINT _method)

{

        if(pThread!=NULL)

        {

                AfxMessageBox("thread가 이미 실행중입니다!");

                return;

        }

 

        pThread = AfxBeginThread( MyThread, this,

                THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);

       

        if(pThread == NULL)

                cout<<"Fail to create camera thread!!";

       

        pThread->m_bAutoDelete = FALSE;

        pThread->ResumeThread();

}

 

//////////////////////////////////////////////////////////////////////////

//

//              Thread 소멸 함수

//

//////////////////////////////////////////////////////////////////////////

bool MyClass::DestroyThread(void)

{

        if(NULL != pThread)

        {

                DWORD dwResult = ::WaitForSingleObject(pThread->m_hThread,INFINITE);

                 

                if(dwResult == WAIT_TIMEOUT)

                        cout<<"time out!"<<endl;

                else if(dwResult == WAIT_OBJECT_0)

                        cout<<"Thread END"<<endl;

               

                delete g_pThread;

 

                pThread = NULL;

        }

        return true;

}

 

//////////////////////////////////////////////////////////////////////////

//

//                      Thread 함수

//     

//////////////////////////////////////////////////////////////////////////

int MyClass::ThreadFunction( void )

{

 

        while ( isThreadRunning )

        {

               

                // Check to see if the thread should die.

                if( !isThreadRunning )

                        break;

 

                // 소스 입력...

                //

        }

        return returnValue;

}



 

[함수 설명]


CWinThread* AfxBeginThread(

   AFX_THREADPROC pfnThreadProc,

   LPVOID pParam,

   int nPriority = THREAD_PRIORITY_NORMAL,

   UINT nStackSize = 0,

   DWORD dwCreateFlags = 0,

   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL 

);

CWinThread* AfxBeginThread(

   CRuntimeClass* pThreadClass,

   int nPriority = THREAD_PRIORITY_NORMAL,

   UINT nStackSize = 0,

   DWORD dwCreateFlags = 0,

   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL 

);


// - msdn :http://msdn.microsoft.com/ko-kr/library/s3w9x78e(v=VS.80).aspx

thread를 생성할 때 사용한다.

pfnThreadProc : 함수의 주소가 들어간다. (반드시 정적함수여야 한다.)

pParam : 스레드로 실행할 함수에 인자로 전달되는 값으로 보통은 주소가 된다.

nPriority: 스레드의 우선순위를 지정한다. 보통으로 사용하기 위해서는 THREAD_PRIORITY_NORMAL 을 쓴다. 

nStackSize: 스레드의 최대 스택 크기를 지정한다. 0을 넣으면 프로세스 생성시 최초 실행되는 스레드의 크기와 같게  

할당된다.

dwCreateFlags: 스레드를 생성한 다음 즉시 실행할 것인지 아니면 대기했다가 실행할 것인지를 명시한다. 

CREATE_SUSPENDED를 사용하면 스레드는 실행되지 않고 대기하게 되며 이 경우 ResumeThread()

함수를 소출하여 스레드를 시작할 수 있다.


 

 


DWORD WaitForSingleObject( 

  HANDLE hHandle, 

  DWORD dwMilliseconds 

); 

// msdn - http://msdn.microsoft.com/ko-kr/library/aa450988

 

::WaitForSingleObject() 함수는 특정 object의 상태가 설정될 때 까지 현재 thread의 실행을 멈추는 역할을 한다. dwMilliseconds 시간만큼 기다리며 이 시간안에 object의 상태가 변화되면 값을 반환한다.

이때 반환값으로 WAIT_TIMEOUT이 반환되면, 기다리는 동안 object의 상태가 설정되지 않아서 그냥 반환했다는 것을 의미하며 WAIT_OBJECT_0를 반환했다면 object의 상태가 설정되어서 반환했다는 것을 의미한다.


여기서 hHandle에는 object의 핸들이나 프로세스의 핸들과 같은 각종 핸들이 들어간다.




[주의]


thread를 종료할 때 thread 함수 안에서 DestroyThread() 함수를 호출하면 thread가 정상적으로 종료 되지 않는다. (무한정 기다리게 되거나..)


그러므로 DestroyThread 함수는 반드시 thread 함수 밖에서 호출 해 줘야한다. (따로 종료 버튼을 만들거나, 메시지 방식 등..)

[출처] [MFC] mfc thread 사용하기 |작성자 hextrial




Posted by injunech
2013.07.09 02:25




TrayIcon.zip


TrayIcon.Z01




1.  프로젝트 생성

-       형식 : MFC 응용프로그램

-       이름 : TrayIcon

-       응용프로그램 종류 : 대화상자 기반 (Dialog based)

2.  프로젝트 생성 후리소스 뷰의 아이콘 중 IDR_MAINFRAME을 자신이 원하는 모양으로 바꿔준다

3.  솔루션 뷰의 헤더파일 중 stdafx.h 파일의 아랫쪽 부분에 다음을 입력

(include 작업의 뒤쪽에 해 주는 것이 좋다.)

이것이 바로 사용자 정의 윈도우 메시지의 설정.(9번과 10번 과정을 꼭 해야함)

 

#define WM_DIALOG_SHOWWM_USER + 101  //다이얼로그감추기/보이기

#define WM_APP_EXIT               WM_USER + 102  //다이얼로그종료

#define WM_TRAYICON               WM_USER + 103  //트레이아이콘메시지

 

4.  CTrayIconMng 클래스를 추가한다기본 클래스는 Cobject.

5.  그리고 CTrayIconMng 클래스의 멤버변수와 함수를 추가 해 준다.

 

        // 트레이아이콘이생성되었는지여부 (True : 생성됨)

        bool m_bAdded;

        // 다이얼로그가감춰진상태인지여부 (True : 숨겨짐)

        bool m_bHide;

        // 팝업메뉴생성

        void MakePopupMenu(HWND hWnd, int x, int y);

        // 팝업메뉴의이벤트발생시처리함수

        void ProcTrayMsg(HWND hWnd, WPARAM wParam, LPARAM lParam);

        // 트레이아이콘생성

        BOOL AddTrayIcon(HWND hWnd);

        // 트레이아이콘제거

        BOOL DelTrayIcon(HWND hWnd);

 

6.  CTrayIconMng 클래스의 멤버함수 코드들을 다음과 같이 각각 작성한다.

// 팝업메뉴생성

void CTrayIconMng::MakePopupMenu(HWND hWnd, int x, int y)

{

  //팝업메뉴를생성하고메뉴구성

  HMENU hMenu = CreatePopupMenu();

  if(m_bHide)            //다이얼로그가감춰진상태라면

        AppendMenu(hMenu, MF_STRING, WM_DIALOG_SHOW, _T("다이얼로그보이기"));

    else                 //다이얼로그가숨겨진상태라면

        AppendMenu(hMenu, MF_STRING, WM_DIALOG_SHOW, _T("다이얼로그감추기"));

 

  AppendMenu(hMenu, MF_STRING, WM_APP_EXIT, _T("종료"));

 

  SetForegroundWindow(hWnd);//생성된팝업메뉴밖을클릭할때팝업닫기

  //팝업메뉴띄우기

    TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, hWnd, NULL);

}

 

 

// 팝업메뉴의이벤트발생시처리함수

void CTrayIconMng::ProcTrayMsg(HWND hWnd, WPARAM wParam, LPARAM lParam)

{

  HMENU hMenu = NULL;

    POINT pos;

 

    if(lParam == WM_LBUTTONDOWN)

    {

        GetCursorPos(&pos);

         MakePopupMenu(hWnd, pos.x, pos.y); //팝업메뉴생성및출력

    }

}

 

// 트레이아이콘생성

BOOL CTrayIconMng::AddTrayIcon(HWND hWnd)

{

  if(m_bAdded)           //이미트레이아이콘이있다면종료

         return FALSE;

 

  NOTIFYICONDATA nid;    //아이콘을생성하여설정

    ZeroMemory(&nid, sizeof(NOTIFYICONDATA));

    nid.cbSize = sizeof(NOTIFYICONDATA);

    nid.hWnd = hWnd;

    nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;

    nid.uCallbackMessage = WM_TRAYICON;

    //sprintf((char*)nid.szTip, (char*)_T("TrayTest"));

 lstrcpy(nid.szTip, "TrayTest"); // tool tip 메세지

    nid.uID = 0;

    nid.hIcon = theApp.LoadIcon(IDR_MAINFRAME);

 

    if(Shell_NotifyIcon(NIM_ADD, &nid)==0) //트레이아이콘표시

        return FALSE;

  m_bAdded = true;      

    return TRUE;

}

 

// 트레이아이콘제거

BOOL CTrayIconMng::DelTrayIcon(HWND hWnd)

{

  NOTIFYICONDATA nid;

 

    ZeroMemory(&nid, sizeof(NOTIFYICONDATA));

    nid.cbSize = sizeof(NOTIFYICONDATA);

    nid.hWnd = hWnd;

    nid.uFlags = NULL;

    if(Shell_NotifyIcon(NIM_DELETE, &nid)==0) //트레이아이콘삭제

        return FALSE;

    return TRUE;

 

}

7.  CTrayIconDlg 에 멤버 변수 및 함수 추가       

// 트레이아이콘관리용객체

  CTrayIconMng m_myTray;

  // 트레이아이콘보이기/숨기기여부

  bool m_bHide;

  long OnTrayIcon(WPARAM wParam, LPARAM lParam);

  void OnAppExit(void);

void OnDialogShow(void);

 

8.  CTrayIconDlg  OnInitDialog() 함수의 마지막부분에 다음을 추가하여 프로그램이 시작됨과 동시에 트레이아이콘을 추가하게끔 함  

 m_myTray.m_bHide = m_bHide;

        m_myTray.AddTrayIcon(GetSafeHwnd());

        return TRUE;  // 컨트롤에 대한 포커스를 설정하지 않을 경우 TRUE를 반환합니다.

 

9.  CTrayIconDlg 에 다음의 함수를 추가 이들은 사용자 메시지 핸들러 역할을 한다

long OnTrayIcon(WPARAM wParam, LPARAM lParam);

void OnAppExit();

void OnToggleShow();

 

10. CTrayIconDlg의 메시지 맵에서 사용자 메시지 핸들러와 연결을 시켜준다

 

BEGIN_MESSAGE_MAP(CMyMessengerDlg, CDialog)

        ON_MESSAGE(WM_TRAYICON, OnTrayIcon)

        ON_COMMAND(WM_APP_EXIT, OnAppExit)

ON_COMMAND(WM_DIALOG_SHOW, OnDialogShow)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

11. CTrayIconDlg 클래스의 함수들을 다음과 같이 지정 해 준다.

(이때, .cpp 파일에 #include "TrayIconMng.h" 가 포함되어야 한다)

 

//트레이아이콘을클릭했을때의메시지핸들러

long CTrayIconDlg::OnTrayIcon(WPARAM wParam, LPARAM lParam)

{

  m_myTray.ProcTrayMsg(GetSafeHwnd(), wParam, lParam);

  return 0;

}

 

//트레이아이콘팝업메뉴의종료메뉴메시지핸들러

void CTrayIconDlg::OnAppExit(void)

{

  m_myTray.DelTrayIcon(GetSafeHwnd());

  CDialog::OnCancel();

}

 

//트레이아이콘보이기/숨기기메뉴메시지핸들러

void CTrayIconDlg::OnDialogShow(void)

{

  if(!m_bHide) ShowWindow(false);       //보이는상태라면숨기고

  else ShowWindow(true);                //숨겨진상태라면보이게

  m_bHide = !m_bHide;

  m_myTray.m_bHide = m_bHide;

}

 

12.  컴파일 및 실행



Posted by injunech