검색결과 리스트
OldPapers/Cplus2 에 해당되는 글 8건
- 2008.07.04 What is 8 Byte Stack Alignment? (PRESERVE8)
- 2007.03.07 __aligin specifier 1
- 2003.06.19 프로퍼티 시트에서 적용과 도움말 버튼 없애기-1
- 2003.06.19 프로퍼티 시트에서 종료 처리
- 2003.06.19 다이얼로그 꾸미기
- 2003.06.19 에디트 컨트롤의 배경색 바꾸기[ReadOnly일 경우 포함]
- 2003.06.19 ListCtontrol 글자색 배경색 Row단위 바꾸기. ( 초간단 )
- 2003.06.19 Dialog based에서 다이얼로그 배경 넣기
2008. 7. 4. 11:10
Byte Stack Alignment
Applies to: Assembler, Compilers, Linker, ARM Developer Suite (ADS), RealView Developer Suite (RVDS) 2.0, RealView Developer Suite (RVDS) 2.1, RealView Developer Suite (RVDS) 2.2, RealView Development Suite (RVDS) 3.0, RealView Development Suite (RVDS) 3.1
What is 8 Byte Stack Alignment?
8 byte stack alignment is a requirement of the ARM Architecture Procedure Call Standard [AAPCS]. This specifies that functions must maintain an 8 byte aligned stack address (e.g. 0x00, 0x08, 0x10, 0x18, 0x20) on all external interfaces. In practice this requirement is met if:
At each external interface, the current stack pointer is a multiple of 8 bytes.
Your OS maintains 8 byte stack alignment on its external interfaces e.g. on task switches
8 byte stack alignment is of particular benefit to processors supporting LDRD and STRD instructions e.g. ARMv5TE. If the stack is not 8 byte aligned the use of LDRD and STRD may cause an alignment fault, depending on the target and configuration used.
8 Byte Stack Alignment in RVCT
In the RealView Compilation Tools (RVCT) v2.0 and above, all generated code and C library code will maintain 8 byte stack alignment on external interfaces. The generated code may not keep the stack 8 byte aligned internally, for example in leaf functions. However all generated code will keep the stack 8 byte aligned providing that it is already correctly aligned at the entry to the function. The compiler will not generate code to correct a mis-aligned stack.
Please be aware that 8 byte stack alignment is not new to RVDS. ADS does maintain 8 byte stack alignment, only the alignment of "double" and "long long" has changed between ADS and RVDS. In ADS "double" and "long long" data types were 4-byte aligned ("EBA4"), unless -Oldrd or __align were used. In RVCT 2.0 and later, double and long long data types are now 8-byte aligned ("EBA8"), unless --apcs /adsabi is used.
The compiler supports the option --apcs /adsabi to compile code that is compatible with the old ADS ABI. However, this is deprecated and will be removed in a future release.
The RVCT tools check 8 byte stack alignment using two build attributes REQUIRE8 and PRESERVE8, these can either be true or false. These are embedded into the object files and executables generated by the tools. REQUIRE8 is used to indicate that the code requires the stack pointer to be 8 byte aligned. PRESERVE8 is used to indicate that the code preserves 8 bytes stack alignment.
The assembler uses the REQUIRE8 and PRESERVE8 directives to indicate whether REQUIRE8 and PRESERVE8 build attributes should be true or false. If you omit PRESERVE8 the assembler will decide whether to set the PRES8 build attribute or not, by examining instructions that modify the SP. ARM recommends that you specify PRESERVE8 explicitly. If your assembly requires the stack to be 8 byte aligned, e.g. LDRD's using SP, you should specify the REQUIRE8 directive.
In RVCT 2.1 and later the assembler (armasm) can generate a warning if it detects a stack access that would leave the stack not 8 byte aligned. This can be enabled by adding --diag_warning 1546 to your assembler command line.
The REQUIRE8 and PRESERVE8 build attributes set by the compiler and assembler are used by the linker to prevent functions that require 8 byte alignment calling functions that do not preserve 8 byte alignment. If this occurs the linker will generate an error, for example:
Error: L6238E: foo.o(.text) contains invalid call from '~PRES8' function to 'REQ8' function
Please see the "Linker Error: L6238E: foo.o(.text) contains invalid call from '~PRES8' function to 'REQ8' function" FAQ for further details.
[출처] What is 8 Byte Stack Alignment?|작성자 두리번
Applies to: Assembler, Compilers, Linker, ARM Developer Suite (ADS), RealView Developer Suite (RVDS) 2.0, RealView Developer Suite (RVDS) 2.1, RealView Developer Suite (RVDS) 2.2, RealView Development Suite (RVDS) 3.0, RealView Development Suite (RVDS) 3.1
What is 8 Byte Stack Alignment?
8 byte stack alignment is a requirement of the ARM Architecture Procedure Call Standard [AAPCS]. This specifies that functions must maintain an 8 byte aligned stack address (e.g. 0x00, 0x08, 0x10, 0x18, 0x20) on all external interfaces. In practice this requirement is met if:
At each external interface, the current stack pointer is a multiple of 8 bytes.
Your OS maintains 8 byte stack alignment on its external interfaces e.g. on task switches
8 byte stack alignment is of particular benefit to processors supporting LDRD and STRD instructions e.g. ARMv5TE. If the stack is not 8 byte aligned the use of LDRD and STRD may cause an alignment fault, depending on the target and configuration used.
8 Byte Stack Alignment in RVCT
In the RealView Compilation Tools (RVCT) v2.0 and above, all generated code and C library code will maintain 8 byte stack alignment on external interfaces. The generated code may not keep the stack 8 byte aligned internally, for example in leaf functions. However all generated code will keep the stack 8 byte aligned providing that it is already correctly aligned at the entry to the function. The compiler will not generate code to correct a mis-aligned stack.
Please be aware that 8 byte stack alignment is not new to RVDS. ADS does maintain 8 byte stack alignment, only the alignment of "double" and "long long" has changed between ADS and RVDS. In ADS "double" and "long long" data types were 4-byte aligned ("EBA4"), unless -Oldrd or __align were used. In RVCT 2.0 and later, double and long long data types are now 8-byte aligned ("EBA8"), unless --apcs /adsabi is used.
The compiler supports the option --apcs /adsabi to compile code that is compatible with the old ADS ABI. However, this is deprecated and will be removed in a future release.
The RVCT tools check 8 byte stack alignment using two build attributes REQUIRE8 and PRESERVE8, these can either be true or false. These are embedded into the object files and executables generated by the tools. REQUIRE8 is used to indicate that the code requires the stack pointer to be 8 byte aligned. PRESERVE8 is used to indicate that the code preserves 8 bytes stack alignment.
The assembler uses the REQUIRE8 and PRESERVE8 directives to indicate whether REQUIRE8 and PRESERVE8 build attributes should be true or false. If you omit PRESERVE8 the assembler will decide whether to set the PRES8 build attribute or not, by examining instructions that modify the SP. ARM recommends that you specify PRESERVE8 explicitly. If your assembly requires the stack to be 8 byte aligned, e.g. LDRD's using SP, you should specify the REQUIRE8 directive.
In RVCT 2.1 and later the assembler (armasm) can generate a warning if it detects a stack access that would leave the stack not 8 byte aligned. This can be enabled by adding --diag_warning 1546 to your assembler command line.
The REQUIRE8 and PRESERVE8 build attributes set by the compiler and assembler are used by the linker to prevent functions that require 8 byte alignment calling functions that do not preserve 8 byte alignment. If this occurs the linker will generate an error, for example:
Error: L6238E: foo.o(.text) contains invalid call from '~PRES8' function to 'REQ8' function
Please see the "Linker Error: L6238E: foo.o(.text) contains invalid call from '~PRES8' function to 'REQ8' function" FAQ for further details.
[출처] What is 8 Byte Stack Alignment?|작성자 두리번
2007. 3. 7. 16:53
출처 : http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=/com.ibm.vacpp6m.doc/compiler/ref/ruoptaln.htm
align
Purpose
Specifies what aggregate alignment rules the compiler uses for file compilation. Use this option to specify the maximum alignment to be used when mapping a class-type object, either for the whole source program or for specific parts.
Syntax
where available alignment options are:
power The compiler uses a set of alignment rules to that provide binary compatibility with objects created by gcc V3.3 using the -malign option. This is the default.
natural The compiler uses a set of alignment rules to that provide binary compatibility with objects created by gcc V3.3 using the -malign option.
mac68k The compiler uses the Macintosh** alignment rules.
bit_packed The compiler uses the bit_packed alignment rules. Data, including bitfields, is packed as tightly as possible.
See also #pragma align and #pragma options.
Notes
If you use the -qalign option more than once on the command line, the last alignment rule specified applies to the file.
You can control the alignment of a subset of your code by using #pragma align=alignment_rule. Use #pragma align=reset to revert to a previous alignment rule. The compiler stacks alignment directives, so you can go back to using the previous alignment directive, without knowing what it is, by specifying the #pragma align=reset directive. For example, you can use this option if you have a class declaration within an include file and you do not want the alignment rule specified for the class to apply to the file in which the class is included.
You can code #pragma align=reset in a source file to change the alignment option to what it was before the last alignment option was specified. If no previous alignment rule appears in the file, the alignment rule specified in the invocation command is used.
Examples
Example 1 - Affecting Only Aggregate Definition
Using the compiler invocation:
xlc++ file2.C /* <-- default alignment rule for file is */
/* power since no alignment rule specified */
Where file2.C has:
extern struct A A1;
typedef struct A A2;
#pragma options align=bit_packed /* <-- use bit_packed alignment rules*/
struct A {
int a;
char c;
};
#pragma options align=reset /* <-- Go back to default alignment rules */
struct A A1; /* <-- aligned using bit_packed alignment rules since */
A2 A3; /* this rule applied when struct A was defined */
Example 2 - Imbedded #pragmas
Using the compiler invocation:
xlc -qalign=mac68k file.c /* <-- default alignment rule for file is */
/* Macintosh */
xlc -qalign=power file.c /* <-- default alignment rule for file */
/* is power */
Where file.c has:
struct A {
int a;
struct B {
char c;
double d;
#pragma options align=bit_packed /* <-- B will be unaffected by this */
/* #pragma, unlike previous behavior; */
/* power alignment rules still */
/* in effect */
} BB;
#pragma options align=reset /* <-- A is unaffected by this #pragma; */
} AA; /* power alignment rules still */
/* in effect */
Using the __align specifier
You can use the __align specifier to explicitly specify data alignment when declaring or defining a data item.
__align Specifier
Purpose
Use the __align specifier to explicitly specify alignment and padding when declaring or defining data items.
Syntax
declarator __align (int_const) identifier;
__align (int_const) struct_or_union_specifier [identifier] {struct_decln_list}
where:
int_const Specifies a byte-alignment boundary. int_const must be an integer greater than 0 and equal to a power of 2.
Notes
The __align specifier can only be used with declarations of first-level variables and aggregate definitions. It ignores parameters and automatics.
The __align specifier cannot be used on individual elements within an aggregate definition, but it can be used on an aggregate definition nested within another aggregate definition.
The __align specifier cannot be used in the following situations:
Individual elements within an aggregate definition.
Variables declared with incomplete type.
Aggregates declared without definition.
Individual elements of an array.
Other types of declarations or definitions, such as typedef, function, and enum.
Where the size of variable alignment is smaller than the size of type alignment.
Not all alignments may be representable in an object file.
Examples
Applying __align to first-level variables:
int __align(1024) varA; /* varA is aligned on a 1024-byte boundary
and padded with 1020 bytes */
static int __align(512) varB; /* varB is aligned on a 512-byte boundary
and padded with 508 bytes */
int __align(128) functionB( ); /* An error */
typedef int __align(128) T; /* An error */
__align enum C {a, b, c}; /* An error */
Applying __align to align and pad aggregate tags without affecting aggregate members:
__align(1024) struct structA {int i; int j;}; /* struct structA is aligned
on a 1024-byte boundary
with size including padding
of 1024 bytes */
__align(1024) union unionA {int i; int j;}; /* union unionA is aligned
on a 1024-byte boundary
with size including padding
of 1024 bytes */
Applying __align to a structure or union, where the size and alignment of the aggregate using the structure or union is affected:
__align(128) struct S {int i;}; /* sizeof(struct S) == 128 */
struct S sarray[10]; /* sarray is aligned on 128-byte boundary
with sizeof(sarray) == 1280 */
struct S __align(64) svar; /* error - alignment of variable is
smaller than alignment of type */
struct S2 {struct S s1; int a;} s2; /* s2 is aligned on 128-byte boundary
with sizeof(s2) == 256 bytes */
Applying __align to an array:
AnyType __align(64) arrayA[10]; /* Only arrayA is aligned on a 64-byte
boundary, and elements within that array
are aligned according to the alignment
of AnyType. Padding is applied after the
back of the array and does not affect
the size of the array member itself. */
Applying __align where size of variable alignment differs from size of type alignment:
__align(64) struct S {int i;};
struct S __align(32) s1; /* error, alignment of variable is smaller
than alignment of type */
struct S __align(128) s2; /* s2 is aligned on 128-byte boundary */
struct S __align(16) s3[10]; /* error */
int __align(1) s4; /* error */
__align(1) struct S {int i;}; /* error */
Related References
Compiler Command Line Options
#pragma align
#pragma pack
See also:
The Data Mapping and Storage section of the VisualAge C++ Programming Tasks manual.
__attribute__((aligned)).
__attribute__((packed)).
align
Purpose
Specifies what aggregate alignment rules the compiler uses for file compilation. Use this option to specify the maximum alignment to be used when mapping a class-type object, either for the whole source program or for specific parts.
Syntax
where available alignment options are:
power The compiler uses a set of alignment rules to that provide binary compatibility with objects created by gcc V3.3 using the -malign option. This is the default.
natural The compiler uses a set of alignment rules to that provide binary compatibility with objects created by gcc V3.3 using the -malign option.
mac68k The compiler uses the Macintosh** alignment rules.
bit_packed The compiler uses the bit_packed alignment rules. Data, including bitfields, is packed as tightly as possible.
See also #pragma align and #pragma options.
Notes
If you use the -qalign option more than once on the command line, the last alignment rule specified applies to the file.
You can control the alignment of a subset of your code by using #pragma align=alignment_rule. Use #pragma align=reset to revert to a previous alignment rule. The compiler stacks alignment directives, so you can go back to using the previous alignment directive, without knowing what it is, by specifying the #pragma align=reset directive. For example, you can use this option if you have a class declaration within an include file and you do not want the alignment rule specified for the class to apply to the file in which the class is included.
You can code #pragma align=reset in a source file to change the alignment option to what it was before the last alignment option was specified. If no previous alignment rule appears in the file, the alignment rule specified in the invocation command is used.
Examples
Example 1 - Affecting Only Aggregate Definition
Using the compiler invocation:
xlc++ file2.C /* <-- default alignment rule for file is */
/* power since no alignment rule specified */
Where file2.C has:
extern struct A A1;
typedef struct A A2;
#pragma options align=bit_packed /* <-- use bit_packed alignment rules*/
struct A {
int a;
char c;
};
#pragma options align=reset /* <-- Go back to default alignment rules */
struct A A1; /* <-- aligned using bit_packed alignment rules since */
A2 A3; /* this rule applied when struct A was defined */
Example 2 - Imbedded #pragmas
Using the compiler invocation:
xlc -qalign=mac68k file.c /* <-- default alignment rule for file is */
/* Macintosh */
xlc -qalign=power file.c /* <-- default alignment rule for file */
/* is power */
Where file.c has:
struct A {
int a;
struct B {
char c;
double d;
#pragma options align=bit_packed /* <-- B will be unaffected by this */
/* #pragma, unlike previous behavior; */
/* power alignment rules still */
/* in effect */
} BB;
#pragma options align=reset /* <-- A is unaffected by this #pragma; */
} AA; /* power alignment rules still */
/* in effect */
Using the __align specifier
You can use the __align specifier to explicitly specify data alignment when declaring or defining a data item.
__align Specifier
Purpose
Use the __align specifier to explicitly specify alignment and padding when declaring or defining data items.
Syntax
declarator __align (int_const) identifier;
__align (int_const) struct_or_union_specifier [identifier] {struct_decln_list}
where:
int_const Specifies a byte-alignment boundary. int_const must be an integer greater than 0 and equal to a power of 2.
Notes
The __align specifier can only be used with declarations of first-level variables and aggregate definitions. It ignores parameters and automatics.
The __align specifier cannot be used on individual elements within an aggregate definition, but it can be used on an aggregate definition nested within another aggregate definition.
The __align specifier cannot be used in the following situations:
Individual elements within an aggregate definition.
Variables declared with incomplete type.
Aggregates declared without definition.
Individual elements of an array.
Other types of declarations or definitions, such as typedef, function, and enum.
Where the size of variable alignment is smaller than the size of type alignment.
Not all alignments may be representable in an object file.
Examples
Applying __align to first-level variables:
int __align(1024) varA; /* varA is aligned on a 1024-byte boundary
and padded with 1020 bytes */
static int __align(512) varB; /* varB is aligned on a 512-byte boundary
and padded with 508 bytes */
int __align(128) functionB( ); /* An error */
typedef int __align(128) T; /* An error */
__align enum C {a, b, c}; /* An error */
Applying __align to align and pad aggregate tags without affecting aggregate members:
__align(1024) struct structA {int i; int j;}; /* struct structA is aligned
on a 1024-byte boundary
with size including padding
of 1024 bytes */
__align(1024) union unionA {int i; int j;}; /* union unionA is aligned
on a 1024-byte boundary
with size including padding
of 1024 bytes */
Applying __align to a structure or union, where the size and alignment of the aggregate using the structure or union is affected:
__align(128) struct S {int i;}; /* sizeof(struct S) == 128 */
struct S sarray[10]; /* sarray is aligned on 128-byte boundary
with sizeof(sarray) == 1280 */
struct S __align(64) svar; /* error - alignment of variable is
smaller than alignment of type */
struct S2 {struct S s1; int a;} s2; /* s2 is aligned on 128-byte boundary
with sizeof(s2) == 256 bytes */
Applying __align to an array:
AnyType __align(64) arrayA[10]; /* Only arrayA is aligned on a 64-byte
boundary, and elements within that array
are aligned according to the alignment
of AnyType. Padding is applied after the
back of the array and does not affect
the size of the array member itself. */
Applying __align where size of variable alignment differs from size of type alignment:
__align(64) struct S {int i;};
struct S __align(32) s1; /* error, alignment of variable is smaller
than alignment of type */
struct S __align(128) s2; /* s2 is aligned on 128-byte boundary */
struct S __align(16) s3[10]; /* error */
int __align(1) s4; /* error */
__align(1) struct S {int i;}; /* error */
Related References
Compiler Command Line Options
#pragma align
#pragma pack
See also:
The Data Mapping and Storage section of the VisualAge C++ Programming Tasks manual.
__attribute__((aligned)).
__attribute__((packed)).
2003. 6. 19. 23:58
위저드에서 생성된 두개의 생 성자에 아래 코드를 추가하십시오...
m_psh.dwFlags |= PSH_NOAPPLYNOW; // 적용버튼 없애기
m_psh.dwFlags &= ~PSH_HASHELP; // 프로퍼티시트의 헬프버튼 없애기
m_Page1.m_psp.dwFlags &= ~PSP_HASHELP; // 이건 시트 위의 페이지마다 하셔야합니다
m_Page2.m_psp.dwFlags &= ~PSP_HASHELP;
m_psh.dwFlags |= PSH_NOAPPLYNOW; // 적용버튼 없애기
m_psh.dwFlags &= ~PSH_HASHELP; // 프로퍼티시트의 헬프버튼 없애기
m_Page1.m_psp.dwFlags &= ~PSP_HASHELP; // 이건 시트 위의 페이지마다 하셔야합니다
m_Page2.m_psp.dwFlags &= ~PSP_HASHELP;
2003. 6. 19. 23:56
CPropertySheet에 맴버 함수로 BOOL ExitCheck()를 만들어줍니다.
각각 Page에 OnQueryCancel() 함수에서 부모에 ExitCheck함수를 불러 메시지 박스를 띄워주고
종료하시겠습니까?? 에서.......종료한다면..... return TRUE, 종료하시 않겠다면 return FALSE를 해주면 됩니다..
예제)
BOOL CSheetPropertySheet::ExitCheck()
{
if ( AfxMessageBox("종료하시겠습니까?", MB_YESNO|MB_ICONQUESTION) == IDYES )
return TRUE;
else
return FALSE;
}
BOOL CPropertyPage::OnQueryCancel()
{
if( ((CSheetPropertySheet*)GetParent())->ExitCheck() )
return CPropertyPage::OnQueryCancel();
else
return FALSE;
}
이렇게 하면 되지요.
각각 Page에 OnQueryCancel() 함수에서 부모에 ExitCheck함수를 불러 메시지 박스를 띄워주고
종료하시겠습니까?? 에서.......종료한다면..... return TRUE, 종료하시 않겠다면 return FALSE를 해주면 됩니다..
예제)
BOOL CSheetPropertySheet::ExitCheck()
{
if ( AfxMessageBox("종료하시겠습니까?", MB_YESNO|MB_ICONQUESTION) == IDYES )
return TRUE;
else
return FALSE;
}
BOOL CPropertyPage::OnQueryCancel()
{
if( ((CSheetPropertySheet*)GetParent())->ExitCheck() )
return CPropertyPage::OnQueryCancel();
else
return FALSE;
}
이렇게 하면 되지요.
2003. 6. 19. 20:46
안녕하세요?
김태인입니다. (이름 말한다고 누가 아나 ㅡ_ㅡ)
김윤환(alf76)님의 요청으로 꼴에 강좌도 하게됐습니다 ㅡ_ㅡ
다이얼로그에 관련된 또는 Document-View 방식의 스킨 씌우는 방법이
참 많죠? 근대 저는 그거 예제들 보면 솔직히 뭔 소린지 모르겠더군요 ㅡ_ㅡ
또한 최근에 나오는 소규모 어플리케이션들(메신저, 간단한 온라인 게임등)을 보면
다 스킨이 씌워져있죠...
그것에 관한 강좌를 간단히 하겠습니다.
최근에 MS 에서 Media Player 7.0 SDK 를 발표하면서 그안에 스킨 기능이 첨가
되었는데...역시 COM 이라서 이쪽에 지식이 없는 사람은 접근하기도 힘들죠...(저도 지식이 없어서 ㅡ_ㅡ)
그래서 저는 주로 MFC에서 모든걸 처리를 하는데...
MFC 기반의 제가 사용하는 법(?)의 스킨을 알려드릴께여...
스킨 = 그림, 스킨에 있는 클릭 가능한(?) 그림 = 이미지 버튼 이라고 생각하면 좋습니다.
예제를 보면서 설명하겠습니다.
void CMyDialog::OnPaint()
{
CPaintDC dc(this);
CDC MemDC;
MemDC.CreateCompatibleDC(&dc);
CBitmap bitmap;
BITMAP bm;
bitmap.LoadBitmap(IDB_BACKGROUND);
bitmap.GetBitmap(&bm);
CBitmap* pOld = dc.SelectObject(&bitmap);
dc.BitBlt(0, 0, bm.bmWidth, bm.Height, &MemDC, 0, 0, SRCCOPY);
dc.SelectObject(pOld);
MemDC.DeleteDC();
}
스킨을 씌우고자 하는 다이얼로그의 OnPaint 이벤트 안에 위의 코드를 추가합니다.
저기서 IDB_BACKGROUND 는 이미지 파일 리소스인데...백그라운드로 쓸이미지를
리소스에 추가하면 됩니다.
위의 소스는 보시면 알겠지만 단순히 그림을 다이얼로그에 출력을 합니다.
그리고 그 그림에 쓸 이미지 버튼들을 만들어야 하는데...
CBitmapButton 이라는 클래스로 만들면 됩니다.
다이얼로그 헤더에 사용할 버튼을 선언합니다.
public:
CBitmapButton click;
void CMyDialog::OnInitDialog()
{
click.Create(NULL, BS_OWNERDRAW | WS_VISIBLE | WS_CHILD, CRect(114, 320, 180, 360), this,
2001);
click.LoadBitmaps(IDB_BITBUTTON);
click.SizeToContent();
}
위의 코드는 비트맵 버튼을 만드는데 IDB_BITBUTTON 이라는 이미지를 사용한다는 뜻입니다.
SizeToContent() 함수는 버튼을 그 이미지 크기만큼 자동으로 조정해줍니다.
그리고 버튼 Create 시에 BS_OWNERDRAW 속성이 있어야 비트맵 버튼으로 생성이 됩니다.
그 버튼에 ON_BN_CLICKED 이벤트만 추가해 주면 되겠죠?
그럼 클릭이 생기죠....
별거 아니죠?
이게 전부입니다.
정리를 하자면...
OnPaint() 에서 그 백그라운드에 쓸 이미지를 불러서 걍 뿌려줍니다.
그리고 OnInitDialog 에서는 비트맵 버튼으로 사용할 버튼을 쭉 만들어서 로딩하면 되고
그 버튼에 대한 이벤트만 추가한 후 처리를 하면 됩니다.
아주아주 간단하죠?
더 간단한 방법이 있을지 모르겠지만 ㅡ_ㅡ
위의 방법이 제가 주로 사용하는 다이얼로그에서의 스킨 방법입니다.
냠...별거 아니었나여 ㅡ_ㅡ
그래도 DevChip 좀 눌러줘여 ^^;
그럼 즐푸하세여~
김태인입니다. (이름 말한다고 누가 아나 ㅡ_ㅡ)
김윤환(alf76)님의 요청으로 꼴에 강좌도 하게됐습니다 ㅡ_ㅡ
다이얼로그에 관련된 또는 Document-View 방식의 스킨 씌우는 방법이
참 많죠? 근대 저는 그거 예제들 보면 솔직히 뭔 소린지 모르겠더군요 ㅡ_ㅡ
또한 최근에 나오는 소규모 어플리케이션들(메신저, 간단한 온라인 게임등)을 보면
다 스킨이 씌워져있죠...
그것에 관한 강좌를 간단히 하겠습니다.
최근에 MS 에서 Media Player 7.0 SDK 를 발표하면서 그안에 스킨 기능이 첨가
되었는데...역시 COM 이라서 이쪽에 지식이 없는 사람은 접근하기도 힘들죠...(저도 지식이 없어서 ㅡ_ㅡ)
그래서 저는 주로 MFC에서 모든걸 처리를 하는데...
MFC 기반의 제가 사용하는 법(?)의 스킨을 알려드릴께여...
스킨 = 그림, 스킨에 있는 클릭 가능한(?) 그림 = 이미지 버튼 이라고 생각하면 좋습니다.
예제를 보면서 설명하겠습니다.
void CMyDialog::OnPaint()
{
CPaintDC dc(this);
CDC MemDC;
MemDC.CreateCompatibleDC(&dc);
CBitmap bitmap;
BITMAP bm;
bitmap.LoadBitmap(IDB_BACKGROUND);
bitmap.GetBitmap(&bm);
CBitmap* pOld = dc.SelectObject(&bitmap);
dc.BitBlt(0, 0, bm.bmWidth, bm.Height, &MemDC, 0, 0, SRCCOPY);
dc.SelectObject(pOld);
MemDC.DeleteDC();
}
스킨을 씌우고자 하는 다이얼로그의 OnPaint 이벤트 안에 위의 코드를 추가합니다.
저기서 IDB_BACKGROUND 는 이미지 파일 리소스인데...백그라운드로 쓸이미지를
리소스에 추가하면 됩니다.
위의 소스는 보시면 알겠지만 단순히 그림을 다이얼로그에 출력을 합니다.
그리고 그 그림에 쓸 이미지 버튼들을 만들어야 하는데...
CBitmapButton 이라는 클래스로 만들면 됩니다.
다이얼로그 헤더에 사용할 버튼을 선언합니다.
public:
CBitmapButton click;
void CMyDialog::OnInitDialog()
{
click.Create(NULL, BS_OWNERDRAW | WS_VISIBLE | WS_CHILD, CRect(114, 320, 180, 360), this,
2001);
click.LoadBitmaps(IDB_BITBUTTON);
click.SizeToContent();
}
위의 코드는 비트맵 버튼을 만드는데 IDB_BITBUTTON 이라는 이미지를 사용한다는 뜻입니다.
SizeToContent() 함수는 버튼을 그 이미지 크기만큼 자동으로 조정해줍니다.
그리고 버튼 Create 시에 BS_OWNERDRAW 속성이 있어야 비트맵 버튼으로 생성이 됩니다.
그 버튼에 ON_BN_CLICKED 이벤트만 추가해 주면 되겠죠?
그럼 클릭이 생기죠....
별거 아니죠?
이게 전부입니다.
정리를 하자면...
OnPaint() 에서 그 백그라운드에 쓸 이미지를 불러서 걍 뿌려줍니다.
그리고 OnInitDialog 에서는 비트맵 버튼으로 사용할 버튼을 쭉 만들어서 로딩하면 되고
그 버튼에 대한 이벤트만 추가한 후 처리를 하면 됩니다.
아주아주 간단하죠?
더 간단한 방법이 있을지 모르겠지만 ㅡ_ㅡ
위의 방법이 제가 주로 사용하는 다이얼로그에서의 스킨 방법입니다.
냠...별거 아니었나여 ㅡ_ㅡ
그래도 DevChip 좀 눌러줘여 ^^;
그럼 즐푸하세여~
2003. 6. 19. 20:44
몇일전에 질문란에 질문으로 올라왔던 에디트 컨트롤에서 ReadOnly 시켰을때 글자가 잘안보인다고,
에디트 컨트롤에 배경색을 좀 바꿨으면 한다는 글을 읽었었는데..
그때 좀 바빠서 답변을 못했었는데, 혹시라도 지금도 찾고 계실까봐 팁란에 올립니다.
다이얼로그 박스 안에 여러개의 에디트 컨트롤이 있는데...
오직 한개의 컨트롤에 다른 컨트롤과 다른 색상을 주고 싶을때...
이것을 어떻게 구현해야 할까요??
간단합니다. 아래의 예를 보시죠.. ^^;
[일반적인 예]
먼저 들어가기에 앞서.. m_Brush 즉 브러쉬를 검은색으로 잡았다고 가정하고...
ClassWizard를 이용하여, WM_CTLCOLOR 메시지에 대한 Method를 작성합니다.
HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
CEdit * pEdit = (CEdit *)GetDlgItem(IDC_EDIT_TEST); //에디트 컨트롤의 포인터를 얻음
if((nCtlColor == CTLCOLOR_EDIT) && (pEdit->GetSafeHwnd() == pWnd->GetSafeHwnd())) {
pDC->SetBkMode(TRANSPARENT); //백그라운드 모드를 설정
pDC->SetTextColor(RGB(255,255,255)); //텍스트의 색깔을 흰색으로..
return m_Brush; //브러시를 리턴
}
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
nCtlColor값과 CTLCOLOR_EDIT값이 동일하고,
pEdit->GetSafeHwnd()와 pWnd->GetSafeHwnd()의 핸들이 동일할 경우에
(여기서 포인터를 비교하지 않고 핸들을 비교하는 이유는 포인터는 유동적, 즉 임시적이지만
핸들은 거의 유동적이지 않기 때문입니다.)
텍스트의 색깔을 흰색으로 처리하고 브러쉬 객체를 삭제해 줍니다.
[읽기 전용일때]
설정은 위에서와 마찬가지 이고...
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
CEdit * pReadOnlyEdit = (CEdit *)GetDlgItem(IDC_EDIT_READONLY); //Read Only 에디트 컨트롤의 포인터
HWND hWndReadOnly = pReadOnlyEdit->GetSafeHwnd();
if(nCtlColor == CTLCOLOR_STATIC && hWndReadOnly == pWnd->GetSafeHwnd()) {
pDC->SetBkColor(RGB(0,0,0)); //배경색을 브러시와 같은 색깔로 설정
pDC->SetTextColor(RGB(255,255,255)); //텍스트의 색깔을 흰색으로....
return m_Brush; //브러쉬를 리턴
}
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
백그라운드 모드를 TRANSPARENT로 두지 않고 적당한 컬러로 텍스트의 백 컬러를 설정할수 있습니다.
위에 보인 예에서 처럼요.. ^^;;
팁으로 위장한 팁이었습니다. ^^;
에디트 컨트롤에 배경색을 좀 바꿨으면 한다는 글을 읽었었는데..
그때 좀 바빠서 답변을 못했었는데, 혹시라도 지금도 찾고 계실까봐 팁란에 올립니다.
다이얼로그 박스 안에 여러개의 에디트 컨트롤이 있는데...
오직 한개의 컨트롤에 다른 컨트롤과 다른 색상을 주고 싶을때...
이것을 어떻게 구현해야 할까요??
간단합니다. 아래의 예를 보시죠.. ^^;
[일반적인 예]
먼저 들어가기에 앞서.. m_Brush 즉 브러쉬를 검은색으로 잡았다고 가정하고...
ClassWizard를 이용하여, WM_CTLCOLOR 메시지에 대한 Method를 작성합니다.
HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
CEdit * pEdit = (CEdit *)GetDlgItem(IDC_EDIT_TEST); //에디트 컨트롤의 포인터를 얻음
if((nCtlColor == CTLCOLOR_EDIT) && (pEdit->GetSafeHwnd() == pWnd->GetSafeHwnd())) {
pDC->SetBkMode(TRANSPARENT); //백그라운드 모드를 설정
pDC->SetTextColor(RGB(255,255,255)); //텍스트의 색깔을 흰색으로..
return m_Brush; //브러시를 리턴
}
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
nCtlColor값과 CTLCOLOR_EDIT값이 동일하고,
pEdit->GetSafeHwnd()와 pWnd->GetSafeHwnd()의 핸들이 동일할 경우에
(여기서 포인터를 비교하지 않고 핸들을 비교하는 이유는 포인터는 유동적, 즉 임시적이지만
핸들은 거의 유동적이지 않기 때문입니다.)
텍스트의 색깔을 흰색으로 처리하고 브러쉬 객체를 삭제해 줍니다.
[읽기 전용일때]
설정은 위에서와 마찬가지 이고...
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
CEdit * pReadOnlyEdit = (CEdit *)GetDlgItem(IDC_EDIT_READONLY); //Read Only 에디트 컨트롤의 포인터
HWND hWndReadOnly = pReadOnlyEdit->GetSafeHwnd();
if(nCtlColor == CTLCOLOR_STATIC && hWndReadOnly == pWnd->GetSafeHwnd()) {
pDC->SetBkColor(RGB(0,0,0)); //배경색을 브러시와 같은 색깔로 설정
pDC->SetTextColor(RGB(255,255,255)); //텍스트의 색깔을 흰색으로....
return m_Brush; //브러쉬를 리턴
}
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
백그라운드 모드를 TRANSPARENT로 두지 않고 적당한 컬러로 텍스트의 백 컬러를 설정할수 있습니다.
위에 보인 예에서 처럼요.. ^^;;
팁으로 위장한 팁이었습니다. ^^;
2003. 6. 19. 20:43
// 0. ListControl을 상속한 클래스의 헤더파일에 다음과 같은 함수를 선언해 줍니다.
afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
// 1. ListControl을 상속한 클래스 CPP파일의 메세지 맵에 다음과 같이 적어줍니다.
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
// 2. 메시지 처리함수를 다음과 같이 만듭니다.
void CMyListControl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;
int iRow;
switch(lplvcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
*pResult = CDRF_DODEFAULT;
iRow = lplvcd->nmcd.dwItemSpec;
lplvcd->clrTextBk = RGB(220, 220, 220);
lplvcd->clrText = RGB(0, 0, 0);
break;
default:
*pResult = CDRF_DODEFAULT;
}
}
// 3. 코드 중간에 보이는 iRow의 값은 현재 그릴 Row의 숫자이고, 그 아랫줄의
// RGB 를 편집하면, 각 Row 마다 각각 다른 글자색과 배경색을 가지고 ListControl을
// 만들수 있습니다.
afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
// 1. ListControl을 상속한 클래스 CPP파일의 메세지 맵에 다음과 같이 적어줍니다.
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
// 2. 메시지 처리함수를 다음과 같이 만듭니다.
void CMyListControl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;
int iRow;
switch(lplvcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
*pResult = CDRF_DODEFAULT;
iRow = lplvcd->nmcd.dwItemSpec;
lplvcd->clrTextBk = RGB(220, 220, 220);
lplvcd->clrText = RGB(0, 0, 0);
break;
default:
*pResult = CDRF_DODEFAULT;
}
}
// 3. 코드 중간에 보이는 iRow의 값은 현재 그릴 Row의 숫자이고, 그 아랫줄의
// RGB 를 편집하면, 각 Row 마다 각각 다른 글자색과 배경색을 가지고 ListControl을
// 만들수 있습니다.
2003. 6. 19. 20:36
http://www.codeproject.com/dialog/bmpdlg01.asp
이곳을 참조
쓸만한 클래스 있음
이곳을 참조
쓸만한 클래스 있음