달력

102011  이전 다음

개인적으로 STL Container를 이용한 동적할당을 자주 사용하는 편이다.

데이터의 수정과 복사등에 편리하기 때문이다.

그러나 삭제시 매번 Loop를 돌아서 참 귀찮았다..

그래서 그 항목들을 모아봤다.

// 이렇게 삭제 대상을 모아놓고...
typedef struct _rmv_stl_inst{
public:
_rmv_stl_inst(void){}
void operator() (LP_TMA_OWNSHIP_INFO& _val) { delete _val; }
void operator() (LP_TMA_TRACKING_INFO& _val) { delete _val; }
}_RMV_STL_INST;

// 이렇게 호출해 버린다...
std::for_each( m_vecOwnshipHistory.begin(), m_vecOwnshipHistory.end(), _RMV_STL_INST() );


혹은.. 
class U2INTERFACEDll _AGRTM_RMV_STL_INSTANCE{
public:
_AGRTM_RMV_STL_INSTANCE(void){}
void operator() (LP_TIF_TRACKING_INFO& _val) { delete _val; } // TrackingInfo
void operator() (LP_TIF_SENSOR_INFO& _val) { delete _val; } // SensorInfo
void operator() (LP_TIF_OWNSHIP_INFO& _val) { delete _val; } // OwnshipInfo
void operator() (LP_TIF_TGT_DROP_INFO& _val) { delete _val; } // Tartget DropInfo

void operator() (LP_RCV_SCANSET_STC& _val) { delete _val; } // ScanSet
void operator() (LP_RCV_SCANSET_DYN& _val) { delete _val; } // ScanSet
void operator() (LP_TRACKING_SCANSET& _val) { delete _val; } // ScanSet
};

이렇게 선언해 놓고... 사용하기도 하고..
std::for_each(
m_vecOwnshipHistory.begin(),
m_vecOwnshipHistory.end(), 
_AGRTM_RMV_STL_INSTANCE()
);

 아예 람다를 쓰기도 한다.
 if( m_vecTrackingHistory.empty() == false ){
std::for_each( 
m_vecTrackingHistory.begin(), 
m_vecTrackingHistory.end(), 
[](LP_TMA_TRACKING_INFO& _val){ delete _val; }
);
m_vecTrackingHistory.clear();
}

Posted by 촌돌애비
|

CurrentControlSet\Services 하위 키


The Services subkeys under the following registry path contain parameters
for the device drivers, file system drivers, and Win32 service drivers:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

The name of each Services subkey is the name of the service, which is also
the root of the name of the file from which the service is loaded. For
example, for the serial mouse, the service name and Services subkey name is
Sermouse. The file from which this is loaded is:

SystemRoot\SYSTEM32\DRIVERS\SERMOUSE.SYS.

All service names are defined under:

     HKEY_LOCAL_MACHINE\SOFTWARE.

The names of the Windows NT built-in network services such as the Alerter
and Browser services are defined under the Microsoft\Windows
NT\CurrentVersion subkey in the Software area of the Registry.

Each Services key can have additional subkeys. Many services have a Linkage
subkey, which provides data for binding network components, as described in
"Linkage Subkey Entries for Network Components," in the article "Network
Adapter Cards Entries, PART 1." Many services also have a Parameters subkey
that contains entries defined by the service with values for configuring
the specific service.

Values for Parameters subkeys and other service-specific entries are
described in these articles:

Network Adapter Cards Entries
Device Drivers Entries
Network Services Entries

The following standard value entries appear for each Services subkey:

ErrorControl     REG_DWORD     Error constant
Specifies the level of error control for the service as follows:

Error Control  Meaning
Level

0x3 (Critical) Fail the attempted system startup.
               If the startup is not using the
               LastKnownGood control set, switch to
               LastKnownGood. If the startup attempt
               is using LastKnownGood, run a bug-check
               routine.

0x2 (Severe)   If the startup is not using the
               LastKnownGood control set, switch to
               LastKnownGood. If the startup attempt
               is using LastKnownGood, continue on
               in case of error.

0x1 (Normal)   If the driver fails to load or initialize,
               startup should proceed, but display a
               warning.

0x0 (Ignore)   If the driver fails to load or initialize,
               start up proceeds. No warning is displayed.

Group     REG_SZ     Group name
Specifies the name of the group of which the particular service is a
member.
Default: (null)

DependOnGroup     REG_MULTI_SZ     Group name
Specifies zero or more group names. If one or more groups is listed, at
least one service from the named group must be loaded before this service
is loaded.
Default: (empty)

DependOnService     REG_MULTI_SZ     Service name
Specifies zero or more Services subkey names. If a service is listed here,
that named service must be loaded before this service is loaded.
Default: (empty)

ImagePath     REG_DWORD     Path and filename
Specifies a path name. For adapters, this value is ignored.
Default: For a driver:

     systemroot\SYSTEM32\DRIVERS\driverName.SYS

For a service:

     systemroot\SYSTEM32\serviceName.EXE

(where driverName or serviceName is the same as the related Services subkey
name)

ObjectName     REG_DWORD     Object name
Specifies an object name. If Type specifies a WIN32 Service, this name is
the account name that the service will use to log on when the service runs.
If Type specifies a Kernel driver or file system driver, this name is the
Windows NT driver object name that the I/O Manager uses to load the device
driver.
Default: subkeyName

Start     REG_DWORD     Start constant
Specifies the starting values for the service as follows:

START TYPE     LOADER     MEANING

0x0            Kernel     Represents a part of the
(Boot)                    driver stack for the boot
                          (startup) volume and must
                          therefore be loaded by the
                          Boot Loader.

0x1            I/O        Represents a driver to be loaded
(System)       subsystem  at Kernel initialization.

0x2            Service    To be loaded or started
(Auto load)    Control    automatically for all startups,
               Manager    regardless of service type.

0x3            Service    Available, regardless of type,
(Load on       Control    but will not be started until
demand)        Manager    the user starts it (for example,
                          by using the Devices icon in
                          Control Panel).

0x4            Service    NOT TO BE STARTED UNDER ANY
(disabled)     Control    CONDITIONS.
               Manager

The Start value is ignored for adapters. If Type is a Win32 Service value
(as described below), the Start value must specify an Auto, Demand, or
Disabled value.

Tag     REG_DWORD
Specifies a load order within a given group. The value of Tag specifies a
number that is unique within the group of which the service is a member.
The related GroupName entry under the Control\GroupOrderList subkey
specifies a list of tags, in load order.

For example, the following services that are members of the Primary Disk
group could have these values: Tag=4 for the Abiosdsk subkey, Tag=2 for
Atdisk, Tag=1 for Cpqarray, and Tag=3 for Floppy. The value for Primary
Disk under the GroupOrderList subkey will use these Tag values to specify
the defined order for loading these services. As another example, each SCSI
miniport service has a unique Tag value that is used as an identifier in
the SCSI miniport value under the GroupOrderList subkey to define which
SCSI adapter to load first.

Type     REG_DWORD     Type constant

Specifies the type of service as follows:

Service Type   Description

0x1            A Kernel device driver.

0x2            File system driver, which is also
               a Kernel device driver.

0x4            A set of arguments for an adapter.

0x10           A Win32 program that can be started
               by the Service Controller and that
               obeys the service control protocol.
               This type of Win32 service runs in
               a process by itself.

0x20           A Win32 service that can share a process
               with other Win32 services.


For example, when you start Windows NT, the Boot Loader scans the Registry
for drivers with a Start value of 0 (which indicates that these drivers
should be loaded but not initialized before the Kernel) and a Type value of
0x1 (which indicates a Kernel device driver such as a hard disk or other
low-level hardware device driver). The drivers are then loaded into memory
in the order specified as the List value in
CurrentControlSet\Control\ServiceGroupOrder.

http://support.microsoft.com/kb/103000/ko



'창고 > 컴터' 카테고리의 다른 글

Zip 명령어  (0) 2011.09.27
Windows7에서 제어판의 시스템 이미지 백업/복원  (0) 2011.03.03
Posted by 촌돌애비
|

Net User 이용

창고/Command 2011. 10. 19. 10:24
  
NET USER
[사용자 이름 [암호 | *] [옵션]] [/DOMAIN]
         사용자 이름 {암호 | *} /ADD [옵션] [/DOMAIN]
         사용자 이름 [/DELETE] [/DOMAIN]
         사용자 이름 [/TIMES:{시간 | ALL}]
 
 
NET USER는 컴퓨터의 사용자 계정을 만들거나 수정합니다. 
스위치 없이 사용될 경우, 컴퓨터에 있는 사용자 계정을 열거해 줍니다. 
 
사용자 계정 정보는 사용자 계정 데이터베이스에 저장됩니다.  
이 명령은 서버상에서만 실행됩니다.  
 
사용자이름 추가, 삭제, 수정, 또는 보고자 하는 사용자 계정의 이름입니다. 
사용자 계정의 이름은 20자까지 쓸 수 있습니다. 
암호         사용자 계정에 대한 암호를 부여하거나 바꿔줍니다. 
 
암호는 NET ACCOUNTS 명령의 /MINPWLEN 옵션으로 설정된 최저 길이 조건을 만족시켜야 합니다. 
14자까지 쓸 수 있습니다. *  암호를 칠 수 있는 프롬프트 상태로 만들어줍니다. 
암호 프롬프트 에서는 입력된 암호가 보이지 않습니다. 
 
/DOMAIN      현재 도메인의 도메인 컨트롤러에 대한 작업을 수행합니다. 
/ADD            사용자 계정 데이터베이스에 사용자 계정을 추가합니다. 
/DELETE      사용자 계정 데이터베이스에서 사용자 계정을 삭제합니다.  
 
옵션..
----------------------------------------------------------------------- 
/ACTIVE:{YES | NO}      해당 계정을 활성화시키거나 비활성화시킵니다. 해당 계정이 활성화되어 있지 않을 경우
                                    사용자는 서버에 연결할 수 없습니다. 기본설정은 YES입니다. 
 
/COMMENT: "문자열"     사용자의 계정에 관한 설명을 제공합니다. (최고 48자까지 쓸 수 있습니다).
                                    문자열은 인용 부호 안에 넣습니다. 
 
/COUNTRYCODE:nnn     사용자의 도움말과 오류 메시지를 위한 특정 언어 파일을 만들기 위해
                                    운영 시스템의 국가 코드를 이용합니다. 0은 기본 설정 국가 코드를 나타냅니다. 
 
/EXPIRES:{날짜| NEVER}  날짜를 지정해주면 계정이 지정된 날짜에 만료됩니다. 
       NEVER는 시간 제한을 주지 않음을 의미합니다. 
       만료 날짜는 국가 코드에 따라 월/일/년 혹은 일/월/ 년의 형태로 표시합니다. 
       월은 숫자로 하거나 문자로 표 기해도 되고 3자로 약자표기 할 수도 있습니다. 
       년도는 2자 혹은 4자의 숫자로 표기합니다. 
       날짜를 표기할 때는 슬래시(/) (공백이 아니라)를 써서 년월일을 구분합니다.  
/FULLNAME:"이름"            사용자의 전체 이름입니다(사용자이름이라기보다). 이름은 인용부호 안에 넣어줍니다. 
/HOMEDIR:경로명             사용자의 홈 디렉터리에 대한 경로를 지정해줍니다. 경로는 반드시 있어야 합니다. 
 
/PASSWORDCHG:{YES| NO}  사용자가 자신의 암호를 변경할 수 있는지 지정해 줍니다. 기본 설정은 YES입니다.
/PASSWORDREQ:{YES | NO} 사용자 계정에 암호가 있어야 하는지를 지정합니다. 기본설정은 YES입니다. 
 
/PROFILEPATH               사용자의 로그온 프로필 경로를 지정합니다. 
/SCRIPTPATH:경로명      사용자의 로그온 스크립트의 위치입니다. 
/TIMES:{시간 | ALL}     로그온 시간입니다. 요일], 시간]으로 표기되며 1시간씩 늘어나도록 제한됩니다. 
   요일은 영문으로 표기하되 전부 풀어 쓰거나 줄여 쓸 수 있습니다. 
   시간은 12시간 표기법이나 24시간 표기법 둘 다 가능합니다. 
   12시간 표기법으로 쓸 때는 am, pm, a.m., 또는 p.m. 으로 구분시켜줍니다. 
   ALL은 사용자가 항상 로그온할 수 있다는 의미이고
                                   공란은 사용자가 절대로 로그온할 수 없음을 표시합니다. 
   요일과 시간은 쉼표(,)로 구분시켜주고,
                                   요일과 시간을 여러 개 쓸 경우에는 세미콜론(;)으로 구분시킵니다. 
/USERCOMMENT:"문자열"               관리자가 계정에 대한 사용자 설명을 추가하거나 변경시킬 수 있게 해줍니다. 
/WORKSTATIONS:{컴퓨터이름 | *}   사용자가 어느 컴퓨터에서 네트워크로 로그온 할 수 있는지 보여줍니다. 
                                                     최고 8개 컴퓨터까지 보여줍니다.
                                                     목록이 없거나 *일 경우 사용자는 어느 컴퓨터에서도 로그온 할 수 있습니다.    
그룹에 추가하는 방법을 알아보겠습니다.  
----------------------------------------------------------------------- 
해당 명령어는 NET LOCALGROUP 과 NET GROUP가 있습니다.  
LOCALGROUP는 로컬 컴퓨터 그룹에 등록할 때 사용하고,  
GROUP는 도메인 그룹에 등록할 때 사용합니다.  
해당 명령어에 대한 설명은 아래와 같습니다.  
NET GROUP
[  그룹이름 {/ADD  | /DELETE}   그룹이름 사용자이름  {/ADD | /DELETE}   
NET GROUP 서버상의 글로벌 그룹을 추가 하거나, 보여주거나, 정해 줍니다. 변수없이 사용될 경우에는 해당 서버상의 그룹 이름을 보여줍니다.  
그룹이름           추가, 확장 또는 삭제할 그룹이름입니다. 어떤 그룹에 있는 사용자 목록을 보려면 그 그룹의 이름만 입력하면 됩니다. 
/COMMENT:"문자열" 기존의 그룹 또는 새로운 그룹에 대한 설명을 추가합니다.
                                 48자까지 쓸 수 있으며, 문자열은 반드시 인용 부호 안에 넣습니다. 
/DOMAIN            현재 도메인의 도메인 컨트롤러에서 작업을 수행합니다. 
 그렇지 않을 경우, 로컬 컴퓨터에서 작업이 이루어집니다. 
 사용자 이름  그룹에 추가시키거나 그룹에서 삭제하고자 하는 사용자 이름 을 나열합니다.  
 사용자 이름이 여러 개일 경우  공백을 이용 하여 구분합니다. 
/ADD                그룹을 추가하거나 사용자 이름을 그룹에 추가합니다. 
/DELETE              그룹을 삭제하거나 사용자 이름을 그룹에서 제거합니다.  

NET LOCALGROUP 
[ 그룹이름 {/ADD  | /DELETE}   
그룹이름 이름  {/ADD | /DELETE}   
NET LOCALGROUP은 컴퓨터 상의 로컬 그룹을 수정합니다. 
따로 옵션을 주지 않을 경우에는, 컴퓨터상의 로컬 그룹들을 보여 줍니다.  
그룹이름           추가, 확장 혹은 삭제하고자 하는 로컬 그룹 이름입니다. 
로컬 그룹 안에 있는 사용자 또는 글로벌 그룹이 어떤 것들이 있는지 보고자 할 경우 그룹 이름만 주면 됩니다.  
/COMMENT:"문자열"  새로운 또는 기존의 그룹에 관한 설명을 추가합니다. 인용부호 안에 문자열을 넣어 줍니다. 
/DOMAIN             현재 도메인의 주 도메인 컨트롤러에서 작업을 수행합니다.
                                그렇지 않을 경우, 로컬 워크스테이션에서 작업이 이루어집 니다. 
이름 로컬 그룹에 추가시키거나 로컬 그룹에서 삭제하고자 하는
                                사용자 이름이나 그룹 이름을 보여줍니다.  여러 개일 경우 공백을 써서 구분시킵니다.
                                다른 로컬 그룹 이름은 안되고 사용자나 글로벌 그룹이름을 씁니다.                      
  만약에 사용자가 다른 도메인에 속해 있을 경우,
                                사용자 이름을 속해 있는 도메인 이름 뒤에 써 줍니다. (예, SALES\RALPHR) 
 
/ADD               그룹 이름 혹은 사용자 이름을 로컬 그룹에 추가합니다.
                                계정이 설정되어 있는 사용자 혹은 글로벌 그룹만이 로컬 그룹에 추가될 수 있습니다. 
/DELETE                   로컬 그룹에서 그룹 이름 또는 사용자 이름을 삭제합니다.   
그럼 명령어에 대한 예를 간단히 들어보겠습니다.   
----------------------------------------------------------------------- 
net user asdf asdf /add   asdf 사용자를 만듭니다.  
net localgroup administrators asdf /add                           asdf 를 administrators 그룹에 소속 시킵니다.  
net localgroup administrators  
net localgroup administrators asdf /delete                              asdf 를 administrators 그룹에 제외 시킵니다.  
net user asdf /delete  asdf 사용자를 삭제합니다.   
  
  
  

'창고 > Command' 카테고리의 다른 글

관리자 계정으로 장치관리자 열기  (0) 2011.10.18
Net Use 명령어  (0) 2011.07.06
[펌]간단한 Cmd...도스명령어 모음...  (0) 2011.07.06
Posted by 촌돌애비
|
runas /user:Administrator "mmc devmgmt.msc"

 

'창고 > Command' 카테고리의 다른 글

Net User 이용  (0) 2011.10.19
Net Use 명령어  (0) 2011.07.06
[펌]간단한 Cmd...도스명령어 모음...  (0) 2011.07.06
Posted by 촌돌애비
|
일반적으로 주변 마트등에서 구입하는 배터리는

AA 사이즈 기준으로 1.5V.... 그리고 알카라인이네... 뭐네...하는 조건 밖에 없다.

그런데 충전용 전지를 보니... 용량 표현이  xxx mAh 라고 용량이 표시되어 있다.

그럼 mAh의 의미는?

 예를 들면.... 100mAh는..
100 mA(milli Ampere) 를 1hour동안 사용할 수 있는 용량.... 으로 정의될 것이다.

 결국.... Watt로 환산이 가능하다...

즉 1.5V짜리 전지가 1000 mAh 용량이 Full로 있다면.
1.5 x 1000 mAh = 1500 watt가 된다...

여기서 내가 가지고 있는 iPhone의 배터리 정보를 확인해 보면...

3Gs 3.7v , 4.51Whr .. Watt Hour
4는 3.7v, 5.25Whr 이다.

앞의 계산식으로 확인해보면.
3Gs는 4.51 / 3.7 = 1.21891891891 ... 즉...1219 mAh..
4는 5.25 / 3.7 = 1.489189189... 대략 1489 mAh...의 용량 배터리라 볼 수 있을 것 같다.

그러면... 시중에서 팔고 있는 E모사의 충전배터리를 보면 

1.2V 2450mAh라고 쓰여 있다.

2개를 직렬로 연결해서 아이폰 충전시 사용한다면..

2.4V 2450 mAh..(직렬임으로 전압은 승압, 전류는 동일)...
2.4 x 2.450 = 5.880 Whr... 

ㅋ~~ 충전기로 충분하다...

여기서 갑자기...추가적인 궁금증....

1회용으로 팔고 있는 알카라인..등의 배터리 용량은 얼마나 될까?...

그 부분은 추후 다시 써야지~~ To Be Continue....
Posted by 촌돌애비
|
// CListCtrl에서 상속받은 CExtListCtrl...
class CExtListCtrl : public CListCtrl 

void CExtListCtrl::fnSetSelectionMarK(int nIndex, BOOL bADD, BOOL bFocus)
{
        int nCnt = GetItemCount();
if( nCnt == 0 ) return;

int nBefore = SetSelectionMark(nIndex);
if( nBefore >= 0 && bADD == FALSE )             // 기존것 unselect
SetItemState(nBefore, NULL, LVIS_SELECTED|LVIS_FOCUSED); 
 
       // 선택항목 select 
      SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);

       if( bFocus == TRUE )
  SetFocus();
}

ListCtrl에서 외부에서 새로운 것을 선택하는 함수인 SetSelectionMark()라고 되어 있다.

그러나 SetSelectionMark만 수행시키면 외부에서 보았을 때 안 나타나는 경우가 있다.
또한 기존에 선택되어 있는 것까지 모두 선택되는 문제도 있다.  
과거 것을 지우기 위해 선택되었던 항목 역시 SetItemState로 기존부분을 없애는 부분이 필요하다. 

'삽질' 카테고리의 다른 글

GetImageEncoders Function  (0) 2011.11.04
STL에서 동적할당 pointer 삭제 루틴.  (0) 2011.10.31
Oracle 3개 Table 조인  (0) 2011.10.13
[MFC] ON_COMMAND_RANGE 매크로  (0) 2011.10.13
STL map에서 람다를 활용한 value 찾기  (0) 2011.10.11
Posted by 촌돌애비
|

Oracle 3개 Table 조인

삽질 2011. 10. 13. 14:18

// 3개의 Table 조인시 
// 2개는 등가
// 나머지 하나는 비등가 조인...

select 
aa.F_INDEX_A,
aa.F_NUM_A,
bb.F_INDEX_B,
bb.F_NUM_B,
bb.F_DATA_B,
cc.F_INDEX_C
from T_AA aa, T_BB bb, T_CC cc
where
(
bb.F_INDEX_ULTASS_TRACKING IN
(
SELECT  
max(b.F_INDEX_B)
from T_AA a, T_BB b
where
(
(b.F_TIME IS NULL)
AND
(a.F_INDEX_A = b.F_INDEX_A_B)
)
group by b.F_INDEX_A_B
)
AND
(
// aa,bb table에는 데이터가 반드시 있다..(등가 조인)
aa.F_INDEX_A = bb.F_INDEX_A_B
)
AND
(
// cc table에는 데이터가 없을 수도 있다...(비등가 조인)
aa.F_INDEX_A = cc.F_INDEX_A_C(+)
)
)
;
Posted by 촌돌애비
|

MFC에서 연속적으로 연결된 resource id들의 command에 대해서 

하나의 function으로 처리할 수 있는 macro.... 


 
ON_COMMAND_RANGE(id1, id2, memberFxn )
Parameters

id1

Command ID at the beginning of a contiguous range of command IDs.

id2

Command ID at the end of a contiguous range of command IDs.

memberFxn

The name of the message-handler function to which the commands are mapped.

Remarks

The range of IDs starts with id1 and ends with id2.

Use ON_COMMAND_RANGE to map a range of command IDs to one member function. Use ON_COMMAND to map a single command to a member function. Only one message-map entry can match a given command ID. That is, you can't map a command to more than one handler. For more information on mapping message ranges, see Handlers for Message-Map Ranges.

There is no automatic support for message map ranges, so you must place the macro yourself.

Example

// The code fragment below shows how to use ON_COMMAND_RANGE macro
  // to map a contiguous range of command IDs to a single message 
  
  // handler function (i.e. OnRangeCmds() in the sample below). In 
  
  // addition, it also shows how to use CheckMenuRadioItem() to check a 
  
  // selected menu item and makes it a radio item.
  
  BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
     ON_COMMAND_RANGE(ID_COMMAND_RANGECMD1, ID_COMMAND_RANGECMD3, &CChildFrame::OnRangeCmds)
  END_MESSAGE_MAP()
  
  void CChildFrame::OnRangeCmds(UINT nID)
  {
     CMenu* mmenu = AfxGetMainWnd()->GetMenu();
     CMenu* submenu = mmenu->GetSubMenu(5);
     submenu->CheckMenuRadioItem(ID_COMMAND_RANGECMD1, ID_COMMAND_RANGECMD3, 
        nID, MF_BYCOMMAND);
  }
  
Posted by 촌돌애비
|


 // 람다정의
 auto fnLambdaFind = [&nData]( std::map<UINT, INT>::value_type const& itr )->bool{ 
   return nData == itr.second ? true : false;
 };

 // 입력한 nData에 해당하는 것을 map에서 찾기 찾기
 std::map<UINT, INT>::iterator it = std::find( m_mapData.begin(), m_mapData.end(), fnLambdaFind);

Posted by 촌돌애비
|
메시지 리플렉션이란 무엇인가?

윈도우즈 콘트롤들은 자신들의 부모윈도우들에게 자주 통지메시지를 보냅니다.
예를들어 많은 콘트롤들은 색상 통지 메시지(WM_COLOR 또는 이 메시지의 변형)을
부모에게 보내 부모가 컨트롤의 바탕색을 칠할수 있게 합니다.

윈도우즈와 MFC 버전 4.0 이전에서는 부모윈도우(일반적으로 다이알로그)에 이러한
메시지들을 처리할 책임이 있습니다. 이것은 메시지를 처리하는 코드가 부모윈도우
의 클래스에 있어야 하고 이 메시지를 처리하는 모든 클래스에 중복되어야 한다는
것을 의미합니다. 위의 경우에서 커스텀 백그라운드를 가지는 콘트롤을 원하는 모든 
다이알로그는 색상 통지 메시지를 처리해야합니다. 만약 콘트롤 클래스가 자신의 바탕
색을 다룰수 있게 작성이 된다면 코드를 재사용하기가 쉬워질 것입니다.

MFC 4.0 에서는 이 부모 윈도우가 통지메시지를 처리한다는 이 오래된 구조도 계속
사용할수 있습니다.
추가로 MFC 4.0은 통지메시지를 자식윈도우나 부모윈도우 또는 두개의 윈도우 
모두에서 처리할 수 있는 "메시지 리플렉션"이라고 부르는 기능으로 편리하게 코드를
재사용 할 수 있게 해줍니다.
컨트롤 바탕색 문제에서 부모윈도우에 의존하지않고 리플렉트된 WM_CTLCOLOR 메시지를 
처리해줌으로서 자신의 바탕색을 지정하는 콘트롤 클래스를 작성할 수 있습니다.
( 메시지 리플렉션은 윈도우즈에 의해서 구현되지 않고 MFC에 의해서 구현된 것이기 
때문에 메시지 리플렉션이 작동하기 위해서는 부모윈도우 클래스가 반드시 CWnd 또는
CWnd에서 계승된 클래스를 상속받아야 합니다.)

이전의 MFC에서도 owner-drawn 리스트박스의 WM_DRAWITEM 메시지를 처리하는 부분
과 같은 몇개의 특정 메시지에 대해 가상함수로 메시지 리플렉션과 유사한 기능을
제공했었으나 이 새로운 메시지 리플렉션 구조는 일반적이면서 견고합니다.

메시지 리플렉션은 4.0 이전 버전으로 작성된 코드에 대해서 하위 호환성을 갖습니다.

//

만일 당신의 부모 윈도우 클래스에 지정된 메세지나 메세지 범위를 위한 핸들을 
지정한다면 그것은 자신의 핸들러안에서 베이스 클래스 핸들러함수를 부르지 않으로써 
제공된 동일한 메세지를 위한 리플렉트된 메세지 핸들을 오버라이드 하는 것입니다.
예를 들면, 만일 다이얼로그 박스 클래스에 WM_CTLCOLOR 핸들을 지정한다면, 당신의 
핸들링은 어떤 리플래스된 메세지 핸들들을 오버라이드 하는 것입니다.

만일 부모 윈도우 클래스에서 당신의 WM_NOTIFY 메세지들 범위나 WM_NOFIFY 메세지를 
지정 한다면 그러한 메세지(WM_NOTIFY)를 보내는 자식 컨트롤이 ON_NOTIFY_REFLECT() 
를 통한 리플렉트 메세지를 가지지 않는다면 당신의 핸들러가 처리될 겁니다.
만일 메세지 맵에 ON_NOTIFY_REFLECT_EX() 을 사용한다면 메세지 핸들러는 부모 윈도우가
메세지를 다룰수 있게도 않게도 할수 있습니다.
즉, 핸들러가 TRUE 을 리턴하면, 메세지는 부모에 의해서 다뤄지지만, FALSE 을 
리턴한다면 다뤄지지 않습니다. 주목할것은 리플렉트 메세지는 notification 메세지 전에 
다뤄집니다.

WM_NOTIFY 메세지를 보낼때 컨트롤은 그것을 다룰 첫번째 기회를 제공 받습니다.
만일 다른 리플렉트 메세지가 보내진다면 부모 윈도우가 그것을 다룰 첫번째 기회를 
받습니다. 그리고 나서 컨트롤의 리플렉트된 메세지를 받습니다. 
그렇게 하기 위해서 그것은 컨트롤의 클래스 멥에 핸들러 함수나 적절한 엔트리가 
필요합니다.

리플랙트 메세지를 위한 메세지 맵은 일반적인 notifications 과 조금 다릅니다.
그것은 _REFLECT 라는 추가적인 이름의 덪붙여 집니다. 예를 들어 부모에서 WM_NOTIFY 
메세지를 처리 하기 위해서 당신은 부모의 메세지 맵에 ON_NOTIFY 매크로를 사용합니다.
그리고 자식 콘트롤의 리플랙트 메세지를 다룰려면 ON_NOTIFY_REFLECT 매크로를 자식 
콘트롤의 메세지 맵에 사용해야 합니다. 양쪽모두 파라미터들은 틀립니다. 
주목할 점은 클래스 위자드가 대개 당신을 위해서 메세지 맵 엔트리와 올바른 
파라미터들을 구현한 뼈대가 되는 함수들을 추가해 줍니다.

새로운 WM_NOTIFY 메세지를 위한 정보를 위해서 TN061: ON NOTIFY and WM_NOTIFY 
Messages 을 보세요.

- Message-Map Entries and Handler Function Prototypes for Reflected Messages

리플렉트된 콘트롤 Notification 메세지를 다루기 위해서 테이블 밑에 열거 되어 있는 
메세지 맵 매크로와 함수 형들을 사용 하십시요.

클래스위자드는 대개 당신을 위해서 그러한 메세지 맵 엔트리들을 추가해 줍니다. 

메세지 이름에서 리플랙트 매크로 이름으로 변환하기 위해서 앞에는 ON_ 을 뒤에는 
_REFLECT 을 추가해 주십시요. 예를 들면 WM_CTLCOLOR 는 ON_WM_CTLCOLOR_REFLECT 가 됩니다.

다음과 같은 3가지 규칙을 벗어나는 경우가 있습니다.
. WM_COMMAND notifications 을 위한 매크로는 ON_CONTROL_REFLECT 가 있습니다.
. WM_NOTIFY 리플렉션들은 ON_NOTIFY_REFLECT 입니다.
. ON_UPDATE_COMMAND_UI 리플랙션들은 ON_UPDATE_COMMAND_UI_REFLECT 입니다.

위의 각경우에 당신은 핸들러 멤버 함수의 이름을 반드시 지정해야 합니다. 
다른 경우에는 핸들러 함수의 표준이름을 반드시 사용해야 합니다.

함수의 파라미터와 리턴값에 대한 의미는 On 으로 시작하는 함수와 일반함수 밑에 설명 
되어 있습니다.

예를 들면 CtlColor 를 OnCtlColor 에 설명 되어 있습니다.
여러개의 리플랙트된 메세지 핸들러들은 부모윈도우에 있는 동일한 핸들러보다 적은 
파라미터들의 필요합니다.

문서에 공식적인 파라미터 이름들과 함수이름들이 있습니다.

Map entry                                    Function prototype 
ON_CONTROL_REFLECT( wNotifyCode, memberFxn ) afx_msg void memberFxn ( ); 
ON_NOTIFY_REFLECT( wNotifyCode, memberFxn )  afx_msg void memberFxn ( NMHDR * pNotifyStruct, LRESULT* result ); 
ON_UPDATE_COMMAND_UI_REFLECT( memberFxn )    afx_msg void memberFxn ( CCmdUI* pCmdUI ); 
ON_WM_CTLCOLOR_REFLECT( )                    afx_msg HBRUSH CtlColor ( CDC* pDC, UINT nCtlColor ); 
ON_WM_DRAWITEM_REFLECT( )                    afx_msg void DrawItem ( LPDRAWITEMSTRUCT lpDrawItemStruct ); 
ON_WM_MEASUREITEM_REFLECT( )                 afx_msg void MeasureItem ( LPMEASUREITEMSTRUCT lpMeasureItemStruct ); 
ON_WM_DELETEITEM_REFLECT( )                  afx_msg void DeleteItem ( LPDELETEITEMSTRUCT lpDeleteItemStruct ); 
ON_WM_COMPAREITEM_REFLECT( )                 afx_msg int CompareItem ( LPCOMPAREITEMSTRUCT lpCompareItemStruct ); 
ON_WM_CHARTOITEM_REFLECT( )                  afx_msg int CharToItem ( UINT nKey, UINT nIndex ); 
ON_WM_VKEYTOITEM_REFLECT( )                  afx_msg int VKeyToItem ( UINT nKey, UINT nIndex ); 
ON_WM_HSCROLL_REFLECT( )                     afx_msg void HScroll ( UINT nSBCode, UINT nPos ); 
ON_WM_VSCROLL_REFLECT( )                     afx_msg void VScroll ( UINT nSBCode, UINT nPos ); 
ON_WM_PARENTNOTIFY_REFLECT( )                afx_msg void ParentNotify ( UINT message, LPARAM lParam ); 

ON_NOTIFY_REFLECT 와 ON_CONTROL_REFLECT 매크로들은 주어진 메세지를 다루는 
하나의 Object 보다 더 많은 것을 할수 있는 다양함을 가집니다.

Map entry                                       Function prototype 
ON_NOTIFY_REFLECT_EX( wNotifyCode, memberFxn )  afx_msg BOOL memberFxn ( NMHDR * pNotifyStruct, LRESULT* result ); 
ON_CONTROL_REFLECT_EX( wNotifyCode, memberFxn ) afx_msg BOOL memberFxn ( ); 

- Handling Reflected Messages: An Example of a Reusable control
이 예제는 CYellowEdit 라 불리는 재사용을 위한 컨트롤을 만든다.
컨트롤은 단지 노란색 바탕에 검정 글씨라는 점만 제외하고 보통의 에디터 컨트롤과 
하는 것은 같습니다.
CYellowEidt 가 다른 색깔로 나타나게 하므로 멤버함수를 추가하는 것이 쉽게 됩니다.

이 샘플을 실험하기 위해서 다음 단계를 하십시요.
1. 기존의 애플리케이션에 새로운 다이얼로그 박스를 생성한다. 
   당신은 틀림없이 reusable 컨트롤 개발을 위한 애플리케이션을 가져야 한다. 만일 없다면 
   AppWizard 로 생성한다.

2. VC++에 로드된 프로젝트가 있다면 CEdit를 베이스로한 CYellowEdit라 불리우는 새로운 
클래스를 ClassWizard 로 생성한다. 리고 Add to Component Gallery 는 체크된 상태로 나둔다.

3. CYellowEdit 에 3개의 멤버 변수를 추가한다. 
첫번째와 두번째는 테스트와 백그라운드 색깔을 저장하기 위한 것이고 세번째는 백그라운드
페인팅을 위한 브러쉬 저장 공간이다. 
CBrush object 는 한번 생볕홱? 단지 후에 그것을 참조 하고 그리고 컨트롤의 파괴될때 
자동으로 없어진다.

4. 생성자에서 다음 멤버값을 초기화 한다.
CYellowEdit::CYellowEdit()
{
 m_clrText = RGB( 0, 0, 0 );
 m_clrBkgnd = RGB( 255, 255, 0 );
 m_brBkgnd.CreateSolidBrush( m_clrBkgnd );
}

5. ClassWizard 를 사용해서 CYellowEdit Class 에 WM_CTLCOLOR 리플렉트 메세지를 추가한다. 
 ClassWizard 다음과 같은 메세지 맵과 구조를 추가해 줄 것이다.

 ON_WM_CTLCOLOR_REFLECT()
 // Note: other code will be in between....
 HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor) 
 {
 // TODO: Change any attributes of the DC here
 // TODO: Return a non-NULL brush if the
 //    parent's handler should not be called
 return NULL;
 }


6. 다음 코드로 함수를 수정해라. 다음 코드는 텍스트 색깔과 텍스트 백그라운드 색깔, 그리고 
컨트롤 리셋을 위한  백그라운드 색깔을 지정한다.

pDC->SetTextColor( m_clrText );    // text
pDC->SetBkColor( m_clrBkgnd );    // text bkgnd
return m_brBkgnd;                // ctl bkgnd


7. 다이얼로그 박스에 에디터 컨트롤을 만들어라. 그리고 나서 컨트롤 키를 누른 상태에서 
에디터 컨트롤을 더블 클릭하므로써 멤버 변수를 추가해라. 다이얼로그 박스의 멤버 추가 
박스에서 멤버변수를 끝내고 category 를 Control를
선택하고 Vaiable Type을 "CYellowEidt"로 선택하라. 
잊지말것은 다이얼로그 박스에서 tab 순서를 선택하는 것이다. 
또한, 다이얼로그 박스의 헤더 화일에 CYellowEdit 컨트롤을 위한 헤더화일을 포함해라.

8. 애플리케이션을 Build 하고 실행하라 . 에디터 박스는 노란색 바탕을 가질 것이다.

9. 당신은 다른 프로젝트들에서 CYellowEdit Control CLass 을 추가하기위해서 
Component Gallery 을 지금 사용해라.
Posted by 촌돌애비
|