'mfc'에 해당되는 글 4건

  1. 2008/05/29 윈도우 시작프로그램에 등록하기(레지스트리 건드려서..) by 모니터에습기찼어
  2. 2008/03/15 [DevPia] MFC vs. ATL by 모니터에습기찼어
  3. 2008/01/30 C++/MFC공부할때 팁 by 모니터에습기찼어
  4. 2008/01/30 프로세스이름으로 검색 및 죽이기 by 모니터에습기찼어

우선.. 윈도우 시작프로그램에서 실행할 프로그램에관련된 레지스트리..

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

이곳에 모든 정보가 저장되어있다.. (윈도 부팅시 실행될 프로그램관련정보들이..)

이거만 알면...

레지스트리 읽기/쓰기 함수를 통해서 건드리면 될거같다..

int ReadRegVal(char *reg_path, char *key, char *val, int val_buf_size ) // reg읽기

{

    HKEY phk=0;

    DWORD nEC = REG_BINARY;                                         // 바이너리모드로 읽기

    DWORD size = val_buf_size;                                            // 레지스트리읽기시 버퍼크기

  

    memset(val,0,val_buf_size);                                              //mem clear

  

    RegOpenKey(HKEY_LOCAL_MACHINE,reg_path,&phk);

    RegQueryValueEx(phk, key, NULL,&nEC, (LPBYTE)val, &size );  //읽기 값은 val에 저장

   //val은 걍 맘편히 타입케스팅 바로 하셔서 쓰셔욧....

    RegCloseKey(phk);


    return 0;

}


int WriteRegVal(char *reg_path, char *key, char *val)          //reg write

{

    HKEY phk=0;

    long nRet;


    RegCreateKey(HKEY_LOCAL_MACHINE, reg_path, &phk);

    nRet = RegSetValueEx(phk, key, 0, REG_SZ, (LPBYTE)val, strlen(val));

  

    RegCloseKey(phk);

  

    if(ERROR_SUCCESS == nRet)   return 0;


    return 1;

}



사용법:

레지스터 쓰기.

WriteRegVal("SOFTWARE\\Microsoft\\Windows", "Windows", "5.2" );

Posted by 모니터에습기찼어
[데브피아] MFC vs ATL Copy url
박윤선 2008.02.22 11:03
조회 105   스크랩 0

 질문&답변
 [질문] MFC ActiveX , ATL MFC지원이랑 무슨차이죠?  | VC++ 일반
임대진 (vs2002)  임대진님께 메시지 보내기임대진님을 내 주소록에 추가합니다.임대진님의 개인게시판 가기 번호: 678738   / 평점:  (-)  / 읽음:18

안녕하세요

프로젝트 생성할때 보면

MFC ActiveX, ATL MFC 지원 또는 미지원 이 있잖아요?

여기서 mfc actiex랑 ATL mfc지원이랑

다르기때문에 나줘지겠죠!

말 그대로 하나는 ATL을 쓰는거구 하나는 Activex형식으로 짜는거겠지만

웹에 import할 때 덩치는 비슷할 거 같은데....

차이가 뭐에요?



 [답변]...
조희원 (neogeist)  조희원님께 메시지 보내기조희원님을 내 주소록에 추가합니다.조희원님의 개인게시판 가기 번호: 678749   / 평점:  (-)  

mfc activeX는 말그대로 mfc로 액티브액스 만드는거고

mfc atl지원은 프로젝트 안에서 정해주는 속성입니다.

mfc atl라이브러리를 쓰면 체크해줘야죠.

atl은 유틸리티와 많은수의 기능들이 헤더에 선언되어있어서
 atl관련기능을 써도 반드시 atl라이브러리를 임포트할 필요는 없습니다.

문제생기면 그때그때...

 [답변]C++로 COM 을 만든는 방법
김진수 (ekklesiaV)  김진수님께 메시지 보내기김진수님을 내 주소록에 추가합니다.김진수님의 개인게시판 가기 번호: 678778   / 평점:  (-)  


C++ 로 COM Component을 만드는 방법에는 크게 두가지가 있습니다.


하나는 MFC로 만드는 방법.

나머지 하나는 ATL로 만드는 방법.


MFC로 만들면 기존의 MFC 라이브러리의 풍부한 기능을 사용할수 있어

GUI 작업시에 많은 편리함을 제공합니다.


ATL은 GUI 작업시에는 윈 32 라이브러리를 사용해서
작업해야 하는 경우가

많습니다. MFC에 비해 GUI 지원이 약합니다.

ATL 프로젝트에서 MFC 지원의 의미는 보통 CString 클래스를
ATL 프로젝트에서 사용하고

싶을 때 이 부분을 체크해줍니다. 또한 그래픽 관련
MFC 클래스를 사용하기 위해서

체크해줍니다. 이 부분을 옵션으로 설정하게 한 이유는
 MFC 라이브러리가

부피가 커서입니다.


ActiveX 컨트롤은 MFC, ATL 둘다 만둘수 있습니다.


2000년전 까지만해도 느린 인터넷 속도와 낮은 PC 사양으로
ATL 로 COM Component를 만드는 것을

추천 하였으나, 지금 같은 빠른 인터넷 속도와 Giga byte 넘는
메모리에 쿼드 프로세서가 장착한 컴퓨터가

나오는 상황에서는 MFC 로 ActiveX  Control 과 COM  
컴포넌트를 만드는 것이 더 낫겠지요.



 [답변]또 하나 차이점
노영선 (roh0sun)  노영선님께 메시지 보내기노영선님을 내 주소록에 추가합니다.노영선님의 개인게시판 가기 번호: 678808   / 평점:  (-)  

COM 관련 자동 코드 생성이 (기본적인 코드가 자동 생성되죠)

MFC는 매크로 방식이고 ATL은 템플릿 기반 C++ 소스 방식입니다.


당근 코드 보기가 소스 이해는 ATL이 더 쉽죠
(템플릿에 대한 기본적인 지식이 있다면)

MFC는 희한한 매크로가 많이 생기는데

그냥 규정대로 매크로 사용법을 잘 따라주면 별 문제 없지만
뭔가 꼬이기 시작하면 디버깅이 더 어려울 수도 있습니다.

Posted by 모니터에습기찼어
*다이얼로그 기반의 프로그래밍에서
MFC에서 제공하는 메세지맵을 이용하기 보다는 직접 코드를 작성하도록 한다.
커맨드 메세지에 대한 일괄적인 정의를 받기 위해서는 ON_COMMAND_RANGE(id1, id2, memberFxn )를 이용하고
버튼의 이벤트처리를 윟새넌 ON_CONTROL_RANGE(wNotifyCode, id1, id2, memberFxn )
를 이용하도록 한다.

*Format의 다양한 옵션을 알도록 한다.
특히 %.15G라는 옵션은 double형 변수를 15자리 이내에서 값이 있는 자리까지만 출력한다.

*atof(char *)
_wtof(wchar *)
되도록 TCHAR형을 쓰도록 한다.

*변수의 갯수는 가능한한 줄이고 각 변수에 대한 기능도 최대한 중복되거나 겹치지 않게 한다

*Create 란 윈도우자식을 만들어 Cwnd 객체에 붙이는 것
*OnCreate 란 WM_CREATE라는 메세지를 받았을때 베이스클래스에서 상속받은 클래스를 호출하는 것.

*각종 콘트롤도 결국에는 하위 윈도우인 것이다.
콘트롤을 상속받은 클래스의 경우 또한 마찬가지이다. 그러므로 각각의 변형된 콘트롤클래스를 생성하면
윈도우 핸들이 생성되고 일반 윈도우를 사용하듯이 onCreate에서 초기화를 해주고
onPaint에서 그려주는 방식으로 구현하면 된다. 여기서 중요한 것은 클래스를 정의하고 메세지에 대한 정의를 할때
메세지맵을 잘 이용하는 것이 중요하다. 그리고 클래스 추가할때 VS의 도움을 받으면 쉽게 할수 있다.(추가->클래스->MFC클래스->...)

*상속받은 클래스의 경우 클래스 선언부에서 클래스 이름을 클릭하게 되면 우측에 처리가능한 메세지에 뜬다.(VC6.0의 클래스위자드처럼)

*인자의 값이 바뀌었을때 클래스의 초기화에 대한 부분을 정확하게 이해하고 있어야 한다.
예를 들어 개인버튼클래스를 만드는 과제의 경우 버튼의 위치를 바꾸어주는 함수를 구현할때 시작위치만 바꾸어줄 것이 아니라 버튼이미지가 그려지는 리전도 함께 옮겨주어야 한다.
나는 setskin이라는 함수에 리전 옮기는 함수가 있어서 그곳에서만 집착을 했지만 막상 리전을 옮겨주는 함수는 버튼의 위치를 바꾸어주는 함수를 호출했을때 아무 영향도 받지 않았다!?!

*비트맵 출력을 하려고 하는 경우에 메모리에 먼저 그려준 다음에 그려주게 되는데 메모리에 그려주는 위치는 화면상의 위치가 아니라 메모리상의 상대적 위치임을 잊지 말고 있어야 한다.

*WM_CREATE 라는 메세지가 올때.
The framework calls this member function when an application requests that the Windows window be created by calling the Create or CreateEx member function.
윈도우가 생성되어 보여주기 직전에 OnCreate라는 함수가 호출된다.

*WM_PAINT라는 메세지가 올때
OnPaint라는 함수를 호출하게 된다. WM_PAINT메세지는 UpdateWindow | RedrawWindow멤버함수가 호출될때 보내온다.

*PreSubclassWindow 라는 버츄얼 함수는 윈도우가 서브클래싱되기전에 필요한 서브클래싱이 일어나게 하려고 호출된다.
*owner-drawn버튼의 시각적인 요소가 변할때 호출된다.

*보통은 OnPaint와 OnCreate가 쌍이고 PreSubclassWindow와 DrawItem이 쌍으로 작동하게 된다. DrawItem과 OnPaint는 그려주는 영역이 미묘하게 다르다.
우리네 작업에서는 앞의 쌍을 주로 쓰게 된다.

*Owner-drawn이란? 기존에 있는 윈도우 클래스들-ex. 버튼. 정적. 리스트박스 등등-를 상속받아 유사한 속성의 새로운 클래스를 만들 경우 이 임의의 클래스를 owner-drawn class라고 한다.

*리소스의 경우 리소스뷰에서 편집가능한 경우와 코드상에서만 존재해서 수정하려면 리소뷰에서 편집못하고 코드로만 수정가능한 경우 두가지가 있다.

*CWnd클래스의 멤버함수중에 Create라는 함수가 있다. 클래스를 동적 생성하는 함수인데. 마지막 인자 UINT nID는 적당하게 큰수를 주는 것이 좋다. 왜냐하면 특히 다이얼로그 기반의 프로그램일경우
ID 중복으로 인해서 원치 않는 메세지 처리가 일어날수 있다. 예를 들어 아이디가 1일경우 확인 혹은 취소버튼과 아이디가 같은 확률이 아주 높다- 확인 | 취소버튼이 있다면- 그러면 새롭게 생성한 버튼에
서-특히나 owner-drawn일 경우는 더더욱- 메세지가 발생했을 경우에 확인|취소버튼의 메세지처리부와 연결되서 프로그램이 자동 종료될수도 있게 된다. 그러므로 nID는 200이상으로 넉넉하게 주는 것이
좋다. 아니면 메세지 처리를 일일이 해주어도 좋고.

*클래스의 초기회는 항상 신경을 써주어야 할 부분이다. 특히 한 클래스의 객체가 여러개 있을 경우 확실한 초기화 코드가 없다면 중복 생성후에 실행시 메모리 오류가 날 확률이 아주 높다.
윈도우 클래스라면 OnCreate에서, 다이얼로그 기반이라면 InitDialog에서 꼭!꼭!꼭!해주어야 한다.

*MFC SDI형태의 프로그램을 시작하기 위해서는 CView클래스를 상속받은 OnCreate함수를 통해서 일단 빈문서가 생성가능한지 여부를 타진한 다음에 -1이 반환되지 않으면 프로그램이 시작하게 된다.!! 뽀인트는 CView 클래스가 있다는 사실!

*표준콘트롤은 WM_CREATE류의 메세지를 받아서 실행되는 곳에서 Create를 해주어야 한다. SDI경우 view생성자가 아닌 OnCreate에서 생성해주어야 한다.

*윈도우를 새로 그리게 되는경우(invalidate(true))인 상황에서 윈도우는 두가지 메세지를 만들게 된다.
배경을 지우기 위한 WM_ERAGSEBKGND : 이 메세지를 받게 되면 윈도우는 배경용 브러쉬를 이용해서 윈도우를 그리게 된다. 그것이 일종의 지워지는 효과를 내는 것이다. 호출함수는 OnEraseBkgnd
지워진 배경에 그림을 그리기 위한 WM_PAINT : 이 메세지는 윈도우에 원하는 내용을 새로 그리게 되는 메시지이다. 호출함수는 프레임이 윈도우 그려줄때는 OnPaint, 윈도우가 다큐먼트 그려줄때는 OnDraw.


*MFC SDI에서 원하는 윈도우로 활성화시키는 코드 app.c에서 수정해야 함.
m_pMainWnd->MoveWindow(0,0,880,1000);    //윈도우 크기를 재정의한다.
m_pMainWnd->CenterWindow();        //상위 윈도우를 기준으로 중앙에 윈도우를 생성한다.
m_pMainWnd->ShowWindow(SW_SHOW);    //윈도우를 일정한 크기로 보여준다(min, max에 반해서)
m_pMainWnd->UpdateWindow();


///////////////////////////////////////////////////////////////////////////////
*더블버퍼핑의 구현개념. 메모리에 비트맵을 생성하여 그 비트맵정보에 화면에 그리듯 그린 다음에 윈도우에 그려줘야 할때 메모리에 저장된 비트맵 정보를 한번에 BitBlt함으로써 완성이 된다. 단, WM_ERAGEBKGND메세지에 주의할것.
구현예)
CRect rect;
GetClientRect(&rect);        //비트맵을 그려줄 영역을 위한 Rect
m_dcMem.CreateCompatibleDC(pDC);    //메모리 DC를 생성한다.
CBitmap    bitMem;            //메모리에 그릴 비트맵변수를 선언
bitMem.CreateCompatibleBitmap(pDC,1916, 1060);    //메모리에 비트맵을 설정한다. 그림으로 치면 도화지를 만드는 개념인것.
m_dcMem.SelectObject(&bitMem);    //생성한 비트멥을 메모리에 셋팅해준다.

CBrush    brush(RGB(255,255,255));
m_dcMem.FillRect(rect, &brush);    //단지 배경을 흰색으로 만들어주기 위해서 메모리에 한번 그려준 것일뿐 필요에 따라 얼마든지 바뀔수 있는 부분이고 전체적으로는 메모리에 한번 그려준것뿐이다.
DrawKeyboard(&m_dcMem);        //일련의 그림을 메모리에 그려주고 있다.
   
pDC->BitBlt(0, 0, 1916, 1060, &m_dcMem,0 , 0, SRCCOPY);    //윈도우에 보여주어야 하는 순간에 BitBlt한다.

m_dcMem.DeleteDC();    //항상 BitBlt한 이후에는 DC를 삭제해주어야 한다.
bitMem.DeleteObject();

그리고 WM_ERAGEBKGND에서는 return TRUE;를 추가해준다.   
///////////////////////////////////////////////////////////////////////////////////

*해당하는 포인터를 포함하는 윈도우 핸들을 구하는 방법
1. CWnd* A = WindowFromPoint(&point);
A->m_hWnd;
A->GetSafehwnd();

2. HWND B = WindowFromPoint(&point)

의미상 같아 보이나 반드시 두번째 방법을 써야 한다.CWnd 구조체를 사용하는 것은 메모리 애러에 대한 보장을 해주지 못할 가능성이 아주 크다.

*현재 포커스가 있는 윈도우 기준이 아닌 스크린 기준의 좌표를 구하는 함수 GetCursorPos(&point);


*define 단어를 만들어 사용할 경우 왠만하면 예약어는 사용하지 않도록 한다.
VS의 단어바꾸기는 대소문자를 구별하지 않기때문에 낭패를 볼수있고 전체솔루션 옵션도 사용하지 않도록 한다.

*dll의 클래스를 다른 플젝에서도 사용할수 있게 하기 위한 것 : class AFX_EXT_CLASS class이름.....


*dll 클래스 작성시 클래스 이름 앞에는 AFX_EXT_CLASS를 넣어주고 클래스 선언 안에는 DECLARE_DYNAMIC(CSPYWINDlg)을
클래스 구현 앞에는 IMPLEMENT_DYNAMIC(CSPYWINDlg, CDialog)을 넣어주어야 한다.

*dll의 출력이름을 바꾸어줄 경우 .def에서 LIBRARY 앞에 ";"를 붙여줘야 한다.

*CTreeCtrl은 트리콘트롤이다. 일반적인 사용은 CString 텍스트를 만들어서 각 아이템에 삽입하고 삭제하는 방식으로 사용한다.
하지만 이것은 화면에 보여지는 것에 대한 정보를 다루는 방법이다. 각 아이템에 정보를 저장해서 보여지는 방법과 다르게 다루어야 할때는
SetItemData와  GetItemData를 사용하여야 한다. 가가 아이템의  HTREEITEM 이름을 가지고 데이터를 삽입하고 삭제하거나 접근이 가능할수 있게되는
함수이다. 트리콘트롤은 각 아이템별로 DWORD 값을 하나 가질수 있는 여지를 만들어 놓았다. 그래서 이 DWORD에 어떤 데이터 혹은 데이터를 가진
구조체의 포인터를 넘겨준다면 어떤 형태의 데이터로 각 아이템이 가질수 있게 되는 것이다. 다음은 각 아이템이 핸들을 가질수 있게 만든 코드이다.
ex) 데이터를 삽입할때
HTREEITEM    leaf =     m_pTree.InsertItem(str,0,1,linked,TVI_LAST);
DWORD    item = (DWORD)present->m_hWnd;
m_pTree.SetItemData(leaf,item);

데이터를 획득할때
HTREEITEM    hItem = m_pTree.GetSelectedItem();
if(hItem != NULL)
{
    DWORD    item = m_pTree.GetItemData(hItem);
    m_selected = (HWND)item;
}
와 같이 사용할수 있다.

*::OutputDebugString(_T(".........."))  - 디버깅상태에서 출력창에 메세지를 출력하게 해줄수 있고, 실행상태에서는 디버거에 메세지를 출력할수 있게 해주는 함수
                                               - 디버깅시에 아주  유용함.(현재 디버그뷰 라는 프로그램을 깔았다)

*%appdata% -> 응용프로그램이 실행되면서 필요한 자료를 받을수 있도록 기본경로가 되는 것. 이것으로 각기 다른 환경에서도 프로그램은 원하는 정보를 찾을수 있다.

*::GetCursorPos -> 현재 마우스 위치를 받아오는 함수



Sort와 stable_sort의 차이
일반 sort는 같은 리스트를 연속으로 키가 같은 경우 sort된 내용이 계속 바뀌게 된다. 하지만 stable_sort는 키가 같은 경우 키를 구별할수 있는 무언가를 찾아낸다
그래서 항상 일정한 sort 결과를 만들어 낼수 있다.
참고 stable_sort에 대한 msdn의 설명이다.
Arranges the elements in a specified range into a nondescending order or according to an ordering criterion specified by a binary predicate and
preserves the relative ordering of equivalent elements.

-------------------------------------------------------------------------------------
출처 : http://blog.naver.com/bmwe3?Redirect=Log&logNo=50026775509
Posted by 모니터에습기찼어
출처 블로그 > Let's Shoveling
원본 http://blog.naver.com/may30jo/70018616184

/* 프로세스 이름으로 프로세스 죽이는 함수 */
bool ProcessKill(CString strProcessName)
{
    HANDLE         hProcessSnap = NULL;
    BOOL           bRet      = FALSE;
    PROCESSENTRY32 pe32      = {0};

    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (hProcessSnap == (HANDLE)-1)
       return false;

    pe32.dwSize = sizeof(PROCESSENTRY32);

    //프로세스가 메모리상에 있으면 첫번째 프로세스를 얻는다
    if (Process32First(hProcessSnap, &pe32))
    {
       BOOL          bCurrent = FALSE;
       MODULEENTRY32 me32       = {0};

       do
       {
         // 모듈을 검색.. 실행파일이 길면 pe32.szExeFile 이걸로 확인불가??
           bCurrent = GetProcessModule(pe32.th32ProcessID,strProcessName);

           if(bCurrent)
           {
               HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,
                                                                     FALSE, pe32.th32ProcessID);

              if(hProcess)
              {
                  if(TerminateProcess(hProcess, 0))
                  {
                     unsigned long nCode; //프로세스 종료 상태
                     GetExitCodeProcess(hProcess, &nCode);
                  }
                 CloseHandle(hProcess);
             }
         }
    }
    while (Process32Next(hProcessSnap, &pe32));

    //다음 프로세스의 정보를 구하여 있으면 루프를 돈다.
  }

  CloseHandle (hProcessSnap);

  return true;
}
/* 프로세스 내의 모듈을 검색하는 함수
* 파일 이름이 길면 모듈의 이름을 검색해서 찾는다
*/
bool GetProcessModule(DWORD dwPID,CString sProcessName)
{
  HANDLE        hModuleSnap = NULL;
  MODULEENTRY32 me32        = {0};

  hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
  if (hModuleSnap == (HANDLE)-1)
    return (FALSE);

  me32.dwSize = sizeof(MODULEENTRY32);

  //해당 프로세스의 모듈리스트를 루프로 돌려서 프로세스이름과 동일하면
  //true를 리턴한다.
  if(Module32First(hModuleSnap, &me32))
  {
    do
    {
      if(me32.szModule == sProcessName)
      {
        CloseHandle (hModuleSnap);
        return true;
      }
    }
    while(Module32Next(hModuleSnap, &me32));
  }

  CloseHandle (hModuleSnap);

  return false;
}

/////////////////////////////////////////////////////////////////////////////////
이걸 잘 활용하면 프로세스 중복실행도 방지할수 있다 ㅋㅋㅋ

Posted by 모니터에습기찼어



Google