WM_ 으로 시작하는 윈도우 메시지를 만들었을때, MFC에서 제공하는 On_ 으로 처리되는 함수들이
자동으로 생성되는 것 보면 편해보이기 까지한다.
이를 수동적으로 생성하는 방법을 알아보자.

WM_USERDEFINE 이라는 메시지가 있다고 하자.
사용자가 만든 메시지여서, 실제 MFC Wizard로 만들수 없다.
게다가, MessageMap 매크로 안에 넣으려해도, afxmsg OnUserDefine 을 만들려고 하면
그 함수와 Message와 연결 할 방법이 없다.
이를 처리하려면, MessageMap 안에서 함수와 Message를 연결해주는 무언가를 만들어 줘야 한다.
그리고, 각 함수를 살펴보면, 윈도우 메시지를 그냥 받는 것이 아니고 각 유형 별로 파라미터로 받는 경우가 있다.
예를 들자면 OnLButtonDown(UINT nFlags, CPoint point) 같은 것은 nFlags 나 point를 받는다.
하지만, 현재는 파라미터가 없는 버젼만을 생각하여 만들도록 하자.

WM_USERDEFINE을 가지고 한번 만들어 보자.

.H 을 열어 보면,
   //{{AFX_MSG(CUserDefine)
   //}}AFX_MSG
   DECLARE_MESSAGE_MAP()
이라는 부분이 있다.
실제로 "//{{AFX_MSG(CUserDefine)",  "//}}AFX_MSG" 이 두 문장은 단순히 클래스 위자드에서 사용하기 위해
만들어진 내용이므로 삭제해도 무방하다. 단 클래스 위자드에 의존하는 분들은 이 부분을 지우게 되면 새로운 메시지
처리를 추가/삭제/수정이 절대 불가능하니, 조심한다.
일단, "//}}AFX_MSG" 아래에다 자신이 만든 메시지 핸들러 함수를 선언한다.
afx_msg 를 맨 앞에 붙이고 그 뒤에 함수 선언을 한다. On 이라는 이름이 붙은 형태의 함수를 만든다.
   afx_msg OnUserDefine()
그러면 .H에서 다 기록한 것이다.

.CPP를 열어보면,
   BEGIN_MESSAGE_MAP(CUserDefine,CWnd )
           //{{AFX_MSG_MAP(CUserDefine)
           ON_WM_PAINT()        
           //}}AFX_MSG_MAP
   END_MESSAGE_MAP()
가 보일 것이다. 이 안이 바로 Message와 함수를 연결해주는 부분이다. 그러나 그 안에 보면 단순히
ON_WM_PAINT()와 같은 단순 무식한 한줄의 함수만 보인다. 그렇다면 이를 어떻게 해야 하는 것인가?
간단하다. ON_WM..  시리즈를 직접 만드는 것이다.
   #define ON_WM_USERDEFINE()
   { WM_USERDEFINE, 0, 0, 0, AfxSig_vv,
   (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))&OnUserDefine },
위의 세줄을 넣어준다.  이 부분이 바로 ON_WM 시리즈의 실체가 된다.
실제 사용되는 WM_ 메시지를 넣고 맨 뒤의 On.. 시리즈 함수를 대체해서 만들어 주면 된다.
위의 예제는 WM_USERDEFINE을 기준으로 넣었다. 그러면 BEGIN_... 안에다 자신이 만든것을 넣어 주면 된다.
   BEGIN_MESSAGE_MAP(CUserDefine,CWnd )
           //{{AFX_MSG_MAP(CUserDefine)
           ON_WM_PAINT()        
           //}}AFX_MSG_MAP
                ON_WM_USERDEFINE()
   END_MESSAGE_MAP()
이렇게 하면 모든것이 해결!

파라미터가 있다면 그 뒤에 다시 생각해보도록한다.
참고로 AfxSig_xxx 라는 값을 이용하면 다양한 형태로 구성할 수 있는 데, 이는 정해진 내용만 적용가능하다.
        AfxSig_bD,      // BOOL (CDC*)
        AfxSig_bb,      // BOOL (BOOL)
        AfxSig_bWww,    // BOOL (CWnd*, UINT, UINT)
        AfxSig_hDWw,    // HBRUSH (CDC*, CWnd*, UINT)
        AfxSig_hDw,     // HBRUSH (CDC*, UINT)
        AfxSig_iwWw,    // int (UINT, CWnd*, UINT)
        AfxSig_iww,     // int (UINT, UINT)
        AfxSig_iWww,    // int (CWnd*, UINT, UINT)
        AfxSig_is,      // int (LPTSTR)
        AfxSig_lwl,     // LRESULT (WPARAM, LPARAM)
        AfxSig_lwwM,    // LRESULT (UINT, UINT, CMenu*)
        AfxSig_vv,      // void (void)

        AfxSig_vw,      // void (UINT)
        AfxSig_vww,     // void (UINT, UINT)
        AfxSig_vvii,    // void (int, int) // wParam is ignored
        AfxSig_vwww,    // void (UINT, UINT, UINT)
        AfxSig_vwii,    // void (UINT, int, int)
        AfxSig_vwl,     // void (UINT, LPARAM)
        AfxSig_vbWW,    // void (BOOL, CWnd*, CWnd*)
        AfxSig_vD,      // void (CDC*)
        AfxSig_vM,      // void (CMenu*)
        AfxSig_vMwb,    // void (CMenu*, UINT, BOOL)

        AfxSig_vW,      // void (CWnd*)
        AfxSig_vWww,    // void (CWnd*, UINT, UINT)
        AfxSig_vWp,     // void (CWnd*, CPoint)
        AfxSig_vWh,     // void (CWnd*, HANDLE)
        AfxSig_vwW,     // void (UINT, CWnd*)
        AfxSig_vwWb,    // void (UINT, CWnd*, BOOL)
        AfxSig_vwwW,    // void (UINT, UINT, CWnd*)
        AfxSig_vwwx,    // void (UINT, UINT)
        AfxSig_vs,      // void (LPTSTR)
        AfxSig_vOWNER,  // void (int, LPTSTR), force return TRUE
        AfxSig_iis,     // int (int, LPTSTR)
        AfxSig_wp,      // UINT (CPoint)
        AfxSig_wv,      // UINT (void)
        AfxSig_vPOS,    // void (WINDOWPOS*)
        AfxSig_vCALC,   // void (BOOL, NCCALCSIZE_PARAMS*)
        AfxSig_vNMHDRpl,    // void (NMHDR*, LRESULT*)
        AfxSig_bNMHDRpl,    // BOOL (NMHDR*, LRESULT*)
        AfxSig_vwNMHDRpl,   // void (UINT, NMHDR*, LRESULT*)
        AfxSig_bwNMHDRpl,   // BOOL (UINT, NMHDR*, LRESULT*)
        AfxSig_bHELPINFO,   // BOOL (HELPINFO*)
        AfxSig_vwSIZING,    // void (UINT, LPRECT) -- return TRUE

        // signatures specific to CCmdTarget
        AfxSig_cmdui,   // void (CCmdUI*)
        AfxSig_cmduiw,  // void (CCmdUI*, UINT)
        AfxSig_vpv,     // void (void*)
        AfxSig_bpv,     // BOOL (void*)

        // Other aliases (based on implementation)
        AfxSig_vwwh,                // void (UINT, UINT, HANDLE)
        AfxSig_vwp,                 // void (UINT, CPoint)
        AfxSig_bw = AfxSig_bb,      // BOOL (UINT)
        AfxSig_bh = AfxSig_bb,      // BOOL (HANDLE)
        AfxSig_iw = AfxSig_bb,      // int (UINT)
        AfxSig_ww = AfxSig_bb,      // UINT (UINT)
        AfxSig_bv = AfxSig_wv,      // BOOL (void)
        AfxSig_hv = AfxSig_wv,      // HANDLE (void)
        AfxSig_vb = AfxSig_vw,      // void (BOOL)
        AfxSig_vbh = AfxSig_vww,    // void (BOOL, HANDLE)
        AfxSig_vbw = AfxSig_vww,    // void (BOOL, UINT)
        AfxSig_vhh = AfxSig_vww,    // void (HANDLE, HANDLE)
        AfxSig_vh = AfxSig_vw,      // void (HANDLE)
        AfxSig_viSS = AfxSig_vwl,   // void (int, STYLESTRUCT*)
        AfxSig_bwl = AfxSig_lwl,
        AfxSig_vwMOVING = AfxSig_vwSIZING,  // void (UINT, LPRECT) -- return TRUE

        AfxSig_vW2,                 // void (CWnd*) (CWnd* comes from lParam)
        AfxSig_bWCDS,               // BOOL (CWnd*, COPYDATASTRUCT*)
        AfxSig_bwsp,                // BOOL (UINT, short, CPoint)
위에서 보듯이 딱 정해진 기능만 하므로... 그 외의 것이라면 다시 생각해보도록 한다.

PS. 혹여 AfxSig_lwl 를 사용하면 WPARAM, LPARAM 이니까... 다양하게 이용할 수 있을지도 모르겠다.

728x90
Linux에서 rdate라는 명령이 있다.
시간 서버에 접속해서 현재 Linux 의 시간을 설정하는 것이다.

이 명령을 보면, rdate -s 가 있는 time host에 접속해 서버 시간을 로컬 시간과 동일하게 만들어 준다.
Time 서버는 일반적으로 time.nist.gov를 사용하면 된다.

728x90
분 시 일 월 요일 권한자 실행내용
ex) 0 0 * * 0 root rdate -s time.nist.gov
   0시 0분 그것도 일요일만 실행을하면 실행권한은 root 이고, rdate 이하를 실행한다.  

/etc/crontab 안의 Text로 해당하는 처리를 하면 된다.
728x90
Winsock의 형태는 다양하게 변모되어 우리에게 다가왔다
sock 라이브러리를 Windows에 맞게 처음 도입한 Winsock 1.x에서 2.x로 발전하고,
MFC로 재 제작하여 배포하고 있다.

여기서 winsock 1.x 때와 2,x 때 include하는 내용이 틀리다.

1. 일반적으로 winsock1.x 라이브러리를 사용하려면,
winsock.h만 include하면 된다. (lib는 일반적으로 섞여 처리된다.)

2. winsock 2.x대에서는 다음의 추가적인 처리가 필요하다.
Winsock2.h 와 ws2tcpip.h 를 include 처리하고
ws2_32.lib를 link시 연결해 주면 된다.

3. MFC 인경우에는 MFC 4.x 대 library안에 lib는 내장되어 있고 단지, 해당 클래스만 include 처리하면 된다.
afxsock.h 가 바로 그 include해야 될 내용이다.
728x90
문득 달력을 보고 있다가, 갑자기 내가 휑하니 여기 까지 왔다는 생각이 든다.
내가 서 있는 위치에서 내가 서있는 길까지의 이 기묘한 기분.
어느새 첫눈도 내렸고, 날씨는 날씨대로 차가워져 있다.
하지만, 뭐 특별히 하는 것 없이 시간을 보내고 있다.
이 진한 커피향 같은 생활속에서 기묘한 여유로움을 가져본다.
가끔 낮에도 잠도 자고 한다.
기묘한 여유로움이 내 몸을 감싸안고 가만히 뒤적거린다.

아아... 지금 난 왜 여기 있지?
728x90
mysql 4.x를 RPM으로..
libiconv 도 prefix = "/usr" 로 설정하고 설치하고...
apache 1.3. x도 RPM으로 되었다면..
/usr/local/freetds 에 MSSQL 라이브러리를 설치하고 난뒤 사용한다.
Gd 라이브러리 포함(단 zlib를 RPM으로 설치되어 있어야함 )

./configure --with-apxs=/usr/sbin/apxs --with-imap=/usr --with-mysql=/usr --with-iconv=/usr --with-language=korean --with-charset=euc_kr --enable-track-vars --enable-module=so  --disable-cgi --with-config-file-path=/etc/httpd/conf --enable-versioning --with-kerberos --with-imap-ssl=/usr   --with-mssql=/usr/local/freetds --enable-msdblib --with-gd  --with-zlib-dir=/usr
728x90
Kernel Compile

  배경지식

기본적으로 커널 소스의 디렉토리는 /usr/src/linux 이다.
커널 컴파일 방법에는 3가지가 있다
make config -> 옵션을 잘못 선택하면 처음부터 다시해야하는 단점이 있다.
make menuconfig -> 가장 추천하는 방법(단, ncurses가 있어야 한다.)
make xconfig -> X에서 볼수 있다.( 화려하다. 그냥 구경한번 해보길...)
시스템 사양을 잘 알아야 한다.(이더넷 카드, 사운드 카드, CPU가 몇개(?)인지등...)
어떠한 환경에서 사용할건지 결정하여야 한다.(커널의 최적화를 위해...)
Kernel Compile Option
꼭 주의깊게 살펴볼것!!(나에게 어떤 옵션이 필요한지 볼것)
제 2회 리눅스 공동체 세미나 자료에서 추출(이규호님께 감사)
커널 2.4 Intro중 커널옵션설정
일반적인 데스크탑 PC사양에서 필요로하는 커널옵션들을 설명하고있다.
  따라하기

커널 소스를 받는다.( http://www.kr.kernel.org/pub/linux/kernel/)
소스를 /usr/src 방으로 옮긴다.(예: mv linux-2.2.12.tar.gz /usr/src )
전에 있던 커널소스 /usr/src/linux 디렉은 다른이름으로 바꾸던지 지워라.(예: mv linux linux-2.2.11)
만약 linux라는 이름으로 심벌릭 링크되어있다면 링크만 해제하라.(예: rm linux)
커널 소스를 푼다.(예: tar xvvzf 커널버전.tar.gz 또는 tar xvvIf 커널버전.tar.bz2)
linux라는 디렉토리가 생겼을 것이다. 그 디렉으로 들어간다.( cd linux )
# make menuconfig ( 현재 위치 /usr/src/linux )
커널 컴파일 옵션을 보고 시스템에 맞는걸 선택한다.(중요하다!)
# make clean (예전 오브젝트 파일 제거)
# make dep (의존성을 검사)
# make bzImage (커널 이미지를 압축생성한다.)
# mv arch/i386/boot/bzImage /boot/vmlinuz-커널버전 (예: mv arch/i386/boot/bzImage /boot/vmlinuz-2.2.12)
# mv System.map /boot/System.map-커널버전 (예: mv System.map /boot/System.map-2.2.12)
# vi /etc/lilo.conf ( 리로를 편집한다 )
     boot=/dev/hda
     map=/boot/map
     install=/boot/boot.b
     prompt
     timeout=50
     image=/boot/vmlinuz-2.2.12 -> 새로운 커널이미지를 linux라는
     label=linux              ?   레이블로 한다.
     root=/dev/hda1
     read-only

     image=/boot/vmlinuz-2.2.11 -> 혹시나 모를 커널 패닉에 대비하여          
     label=old                     예전 커널을 old란 레이블로 해놓는다.
     root=/dev/hda1                (예전 버전이 2.2.11일때)
     read-only
# /sbin/lilo ( lilo.conf의 내용을 인식시켜 주기위해 )
여기까지 커널 컴파일은 과정은 끝.
  모듈 인스톨 하기

커널 옵션에서 모듈(M)으로 선택한것을 컴파일 하기위해
# cd /usr/src/linux
# make modules
# make modules_install
위와같이 하면 '/lib/modules/커널버전' 디렉에 모듈들이 위치한다.


Kernel Patch


패치란 매번 커널이 바뀔때 마다 13MB가 넘는 커널 소스를 다시 받을 필요없이 바뀐 차이점만 담고있는 작은 용량의 파일로 커널을 업하는걸 말한다.
장점 : 적은용량으로 패치파일로 커널을 금방 업 할 수 있다.
단점 : 중간의 한 단계를 건너 뛸 수 없다. 예를들어 현재 커널 버전이 2.2.10 인데 바로 2.2.12로 패치 할 순없다.(꼭 2.2.11을 패치하고 나야 된다)
  따라하기

패치 파일을 다운받아 bzip2이든 gzip으로 압축되어있던지 간에 압축을 푼다.
압축을 푼후 /usr/src/linux 방으로 옮긴다.
# patch -p1 < 패치파일?
에러 없이 넘어가면 다음은 커널 컴파일 과정과 같다.
만약 압축을 풀지않고 패치하려면 gzip 또는 bzip2에 따라 다음과 같이한다.
# gzip -cd 패치파일.gz | patch -p1(물론 패치파일의 위치는 /usr/src/linux)
# bzip2 -cd 패치파일.bz2 | patch -p1
728x90
S(Source)RPM을 받았을 때 사용법

ncftp-3.1.3-6.src.rpm
을 받았다고 치면

# rpm -Uvh ncftp-3.1.3-6.src.rpm
# cd /usr/src/hancom/SPECS
# rpmbuild -ba ncftp.spec

빌드가 끝나면

# cd /usr/src/hancom/RPMS/i386
에 가면
ncftp-3.1.3-6.i386.rpm
이 만들어져 있을 것이다.

# rpm -Uvh ncftp-3.1.3-6.i386.rpm
하면 설치가 끝난다.

지금까지 소스RPM을 받아서 자신 컴에서 빌드하여 설치하는 것을 알아보았다.

그럼 해피 리눅싱~~

발췌 : 한컴 리눅스 >OS Tip & Tech > [팁] SRPM을 RPM으로 만들어서 설치하는 법(멀티)
http://kr.hancom.com/board/bbsView.php?zone=os&from=3&mode=0&sort=0&s_order=0&page=0&info_no=14&zone=os&key=title&value=srpm&cata=&goods=&num=301175
728x90

+ Recent posts

728x90