** 문자열 처리 함수 **

#include

1) 문자열의 길이 측정(strlen)

strlen(문자열)

2) 문자열 결합(strcat)

char *ptr;
ptr = strcat(문자열, 문자열2)

3) 문자열 비교(strcmp)

int i;
i = strcmp(문자열, 문자열2)
i == 0 <--- 같다.
i != 1 같지 않다.

4) 문자열 복사(strcpy)

char *ptr;
strcpy(문자열, 문자열2)
문자열2를 문자열로 복사 5) 문자열 변환(atoi, atol, atof)

atoi -> 정수
atol -> long
atof -> 부동 소수점.

long b; float c;
int a;

a = atoi("1234" );
b = atol("-544334" );
c = atof("43.5456);

6) 문자열 교환 함수 (str_swap)

void str_cpy(char *ptr1, char *ptr2)
{
while(*ptr2)
*ptr1++ = *ptr2++;
*ptr1 = NULL;

}

void str_swap(char *a, char *b)
{
char temp[255];
str_cpy(temp, a)
str_cpy(a, b);
str_cpy(b, temp);
}
7) 문자열 내에서 특정 문자의 개수를 카운트 하는 함수(char_cnt)

int char_cnt(char *ptr, char ch)
{
int i = 0;

wile(*ptr)
if(*ptr++ == ch)
i++;

return(i);

}  

8) 문자열 내의 특정 문자를 다른 문자로 바꾸는 함수(str_chg)

int str_chg(char *ptr, char ch1, char ch2)
{
while(*ptr)
{
if(*ptr == ch1)
*ptr = ch2;

ptr++;
}
}

9) 문자열 내의 특정 문자를 탐색(str_fine)

char *str_find(char *ptr, char ch)
{
while(*ptr)
{
if(*ptr == ch)
return(ptr);
ptr++;
}

return((char *)(-1));

}

10) 문자열 내의 소문자를 대문자로 바꾸는 함수(str_upp)

void str_upp(char *ptr)
{
while(*ptr)
{
if(islower(*ptr))
*ptr = toupper(*ptr);
ptr++;
}
}

11) 문자열 내의 대문자를 소문자로 바꾸는 함수(str_low)

void str_low(char *ptr)
{
while(*ptr)
{
if(isupper(*ptr))
*ptr = tolower(*ptr);
ptr++;
}
}

12) 대문자와 소문자 상호 교환 함수(str_case)

void str_case(char *ptr)
{
while(*ptr)
{
if(isupper(*ptr))
*ptr = tolower(*ptr);
else if(islower(*ptr)
*ptr = toupper(*ptr);
ptr++;
}
}

13) 각 문장의 첫 문자만 대문자로 교환하는 함수(str_fst)

void str_fst(char *ptr)
{
if(islower(*ptr))
*ptr = toupper(*ptr);

while(*ptr)
{
if(*ptr == '.')
{
ptr++;

while(*ptr == ' ')
ptr++;

if(islower(*ptr))
*ptr = toupper(*ptr);
}

break;
}

ptr++;
}

14) 문자열 내의 지정한 위치에 다른 문자열을 삽입하는 함수(str_ins)

char *str_ins(char ptr1[], char ptr2[],int t)
{
char temp[255];
int i, j, k;

if(t>=str_len(ptr1) return (-1);

for(k=0; i=0; i<t; i++; k++)
temp[k] = ptr1[i];

for(j=0; ptr2[j] != NULL; j++, k++)
temp[k] = ptr2[j];

while(ptr1[i])
temp[k++] = ptr1[i++];
temp[k] = NULL;
}

15) 문자열 앞에 지정한 개수 만큼의 공백을 추가하는 함수(str_blk)

void str_blk(char ptr[], int t)
{
static char temp[255];
int i;

for(i = 0; i<t; i++)
temp[i] = BLANK;

temp[i] = NULL;

str_cat(temp, ptr);

str_cpy(ptr, temp);
}

16) 문자열 내의 모든 공백을 삭제하는 함수(rmv_blk)

void rmv_blk(char ptrp[])
{
char temp[255];
int i, k;

for(i=0, k=0; ptr[i] != NULL; i++)
if(ptr[i] != BLANK)
temp[k++] = ptr[i];

temp[k] = NULL;

str_cpy(ptr, temp);
}

17) 문자열 내에서 원하는 개수 만큼 문자를 삭제하는 함수(str_rmv)

void str_rmv(char *ptr, int loc, int count)
{
int len, i, j;
len = str_len(ptr);

if(loc >= len)
return (-1);

if(loc + count <= len)
{
j = loc + count;

for(i=loc; ptr[j] != 0; i++)
{
ptr[i] = ptr[j];
j++;
}
ptr[i] = NULL
}
else
ptr[loc] = NULL;
}

18) 특정한 문자열이 기억된 위치를 계산하는 함수(str_loc)

int str_loc(char ptr1[], char ptr2[])
{
int i, j, k;
for(i=0; ptr1[i] != NULL; i++)
for(j=i, k=0; ptr2[k] == ptr1[j]; k++, j++)
return (i);
return (-1);
}

19) 특정한 문자열이 나온 개수를 카운트 하는 함수(str_cnt)

int str_cnt(char ptr1[], char ptr2[])
{
int i, j, k;
int count = 0;
for(i=0; ptr1[i] != NULL; i++)
for(j=i, k=0; ptr2[k] == ptr1[j]; k++, j++)
if(ptr2[k+1] == NULL)
{
count++;

break;
}
return ((count == 0) ? -1 : count);
}

'개발지식창고 > C' 카테고리의 다른 글

C 문자열 함수 정리  (0) 2010.09.20
BASE64 Encode/Decode  (0) 2010.09.20
printf 특수문자 출력하기  (0) 2010.08.16
32비트 배열을 이용한 상태값 저장 및 얻어오기  (0) 2010.08.16
[C/C++]#define 매크로 팁  (0) 2010.08.16
Posted by 모과이IT
,
1.요약 

ATL 컴포넌트가 특정 키보드 메세지를 받을 수 있는 방법에 대해서 알아봅니다. 


2.본문 

ATL 컴포넌트를 만들게 되면, 웹브라우저가 키보드 메세지를 (Accelerator Key.. 예를 들어 Tab, Delete 같은 키) 컴포넌트로 보내주지 않습니다. 하지만, 웹브라우저가 노출하는 IOleInPlaceActiveObject 인터페이스의 TtranslateAccelerator 함수를 호출하면 됩니다. 물론 WM_KEYDOWN 메세지 핸들러에서 처리해 주시면 됩니다. 하지만, 간혹 WM_KEYDOWN 메세지가 정상적으로 들어오지 않는 경우가 있는데, 이를 위해서 아래와 같이 메세지 펌프를 조작하면 됩니다. 

3.예제

// 메세지 펌프 

while (GetMessage(&msg, NULL, 0, 0)) 

 TranslateMessage(&msg);


 // Send all keyboard messages to the window of your 

 // application. hwndApp is the window handle of 

 // your application. 

 // 

 if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST) 

  ::SendMessage(hwndApp, msg.message, msg.wParam, msg.lParam);


 DispatchMessage(&msg); 

}


// WM_KEYDOWN 메세지 핸들러에서.. 

LRESULT OnKeydown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 

 // m_spWebBrowser is a data member of type IWebBrowser2. 

 // Using CComQIPtr in this way queries m_spWebBrowser 

 // for the IOleInPlaceActiveObject interface which is 

 // then stored in the pIOIPAO variable. 

 // 

 CComQIPtr pIOIPAO(m_spWebBrowser); 

 HRESULT hr = S_FALSE;


 if (pIOIPAO) 

 { 

  MSG msg; msg.message = uMsg; 

  msg.wParam = wParam; 

  msg.lParam = lParam; 

  hr = pIOIPAO->TranslateAccelerator(&msg); 

 } 

 

 return hr; 

}

Posted by 모과이IT
,
IWebBrowser2* GetIWebBrowser2FromCWebBrowser2(CWebBrowser2& wndBrowser) 
IWebBrowser2* piWebBrowser2=NULL; 
if (LPUNKNOWN pUnk = wndBrowser.GetControlUnknown()) 
if (SUCCEEDED(pUnk->QueryInterface( 
IID_IWebBrowser2, (void**)&piWebBrowser2))) 
// Remember to call Release 
return piWebBrowser2; 

return NULL; 

Posted by 모과이IT
,

1. 문자열 복사 하기

단순히 대입만 하면 된다.


CString str1("어쩌구");

CString str2;


str2=str1;       //대입

str2='A';        //단일문자

str2="ABC";   //문자열


2. 문자열 추출 하기

Left, Mid, Right 를 사용하여 추출한다. 직관적으로 왼쪽,중간,오른쪽이라는 것을 알 수 있다.


CString str1("ABCDE");

CString str2;


//왼쪽에서부터 i 개의 글자를 추출하여 Str2에 넣음

str2=str1.Left(i);


//오른쪽에서부터 i개의 글자를 추출하여 Str2에 넣음

str2=str1.Right(i);


//중간에 a번 건너뛰고 i개의 글자를 추출하여 Str2에 넣음

str2=str1.Mid(a,i);


EX) 

str2=str1.Left(3);

printf("%s",str2);       //"ABC"


str2=str1.Right(2);

printf("%s",str2);       //"DE"


str2=str1.Mid(2);

printf("%s",str2);       //"CDE"


str2=str1.Mid(2,2);

printf("%s",str2);       //"CD"


3.문자열 연결하기

신기하게도 더하기 처럼 사용한다.


CString str;


str = "ab";
str = str + "c" + "d";
str += "e";
printf( str );               // "abcde"


4.문자열 비교하기

비교하여 정수를 리턴한다


CString str( "ABC" );
int bRet;


bRet = str.Compare( "ABC" );
//  0 , 같음 "ABC" == "ABC"

bRet = str.Compare( "abc" );
// -1 , 작음 "ABC" < "abc"
 
bRet = str.Compare( "123" );
//  1 , 큼   "ABC" > "123"

bRet = str.CompareNoCase( "abc" );
//  0 , 같음 "ABC" == "abc"

bRet = str.CompareNoCase( "ABC" );
//  0 , 같음 "ABC" == "ABC"


// oprator ==, !=, <, >, <=, >=

( str == "ABC" ) ?  "true" : "false"         // true
( str != "ABC" )  ?  "true" : "false"        // false
( str <  "ABC" ) ?  "true" : "false"        // false
( str >  "ABC" ) ?  "true" : "false"        // false
( str <= "ABC" ) ?  "true" : "false"       // true
( str >= "ABC" ) ?  "true" : "false"       // true



5.문자열 검색하기

찾을 문자열을 쓰면 성공/실패 리턴



int nIndex;
CString str("abcde abc");


nIndex = str.Find( 'a' );
//  0, 성공

nIndex = str.Find( 'k' );
// -1, 실패

nIndex = str.Find( "bc" );
//  1, 성공

nIndex = str.Find( "bcdef" );
// -1, 실패

nIndex = str.Find( "abc", 5 );      //5번째 이후부터 찾고, 찾은 위치 리턴
//  6, 성공

nIndex = str.ReverseFind( 'e' );  //뒤에서부터 찾아 위치 리턴
//  4, 성공




6. 문자세트 검색하기

과연 쓸모가 있을까 하는 기능

가장 비슷한 문자열을 찾아 준다고 하는데...


int nIndex;
CString str( "abcde abc" );


nIndex = str.FindOneOf( "1c23e" );   //이것같은 경우는 c를 찾아서 위치값리턴한다.
//  2, 성공

nIndex = str.FindOneOf( "123" );       //같은게 없으니까 당연히 실패
// -1, 실패



7. 문자세트 추출하기

추출이 진짜 추출이 아닌것같다. 문자열 걸러내기가 더 어울리는 것같은데...ㅎ

 

CString str( "age is 30 ~*^^*" );
CString spnstr;
 

// str은 변하지 않습니다.
// 소문자 a ~ z 그리고 공백 문자가 포함된 문자열까지 추출합니다.

spnstr = str.SpanIncluding( "abcdefghijklmnopqrstuvwxyz " );

// str      출력시   "age is 30 ~*^^*"
// spnstr 출력시   "age is "

 

// "~!@#$%^&*()-=_+[]{},.<>/?;:'`" 를 포함하지 않는 문자열까지 추출합니다.

spnstr = str.SpanExcluding(" ~!@#$%^&*()_=+[]{},.<>/?;:'`" " );

// str      출력시    "age is 30 ~*^^*"
// spnstr 출력시    "age is 30"

 

 

 

8. 문자열의 공백 및 문자 제거하기

제거하고 원래 문자열에 저장까지...이걸쓸껄...ㅋ

 

CString str1( "  abcd \t\n" );
CString str2( "abcd1234" );
CString str3( "(***abcd1234***)" );
 
str1.TrimLeft();                //아무것도 안쓰면 공백 제거하기 왼쪽부터~
// "abcd \t\n"

 

str1.TrimRight();              //\t\n은 개행문자인데 따로 지정안해도 지워져버린다. 오른쪽~
// "abcd"

 

str2.TrimLeft( 'a' );           //특정문자 지정해서 지우기 왼쪽부터~
// "bcd1234"

 

str2.TrimRight( "234" );      //오른쪽부터~
// "bcd1"

 

str3.TrimLeft( "(*" );          //해봐야겠는데...
// "abcd1234***)"

 

str3.TrimRight( "*)" );         //왜 자동으로 **마저 지워지지?
// "abcd1234"

'개발지식창고 > MFC' 카테고리의 다른 글

한글인지 아닌지 판단  (0) 2010.08.22
컨트롤의 색변환  (0) 2010.08.22
CString 관련 함수  (0) 2010.08.17
■ CFile 클래스 : 파일 입출력 클래스  (0) 2010.07.30
WinMain.cpp를 MFC 클래스로 구현하면...  (0) 2010.07.30
Posted by 모과이IT
,

[CString관련 함수]

 

함 수

기 능

Length

문자열 길이 변환

Trim

문자열 앞 뒤의 공백을 삭제

TrimLeft

문자열의 왼쪽 공백을 삭제

TrimRight

문자열의 오른쪽 공백을 삭제

UpperCase

문자열 데이터를 대문자로 변환

LowerCase

문자열 데이터를 소문자로 변환

StrReverse

뒤바뀌어진 문자열을 반환

NumericText

문자열이 숫자이면 True 값 반환

ToNumber

문자열을 숫자로 변환

ToText

숫자를 문자열로 변환

ToWords

숫자를 단어로 변환

ReplicateString

인수로 지정한 값만큼 반복 프린트

Space

인수로 지정한 값만큼 공백문자 출력

Instr

문자열에서 다른 문자열의 위치를 반환

InstrRev

문자열에서 다른 문자열의 위치를 반대로 반환

StrCmp

문자열을 비교해서 결과값을 반환

Mid

문자열에서 지정한 만큼 문자열을 반환

Left

문자열의 좌측으로부터 지정된 수의 문자를 반환

Right

문자열의 우측으로부터 지정된 수의 문자를 반환

Val

문자값을 수치로 변환

Chr

아스키 값에 해당하는 문자 출력

Asc

지정한 문자의 아스키 값을 반환

Filter

Replace

Join

Split

함 수

기 능

Length

문자열 길이 변환

Trim

문자열 앞 뒤의 공백을 삭제

TrimLeft

문자열의 왼쪽 공백을 삭제

TrimRight

문자열의 오른쪽 공백을 삭제

UpperCase

문자열 데이터를 대문자로 변환

LowerCase

문자열 데이터를 소문자로 변환

StrReverse

뒤바뀌어진 문자열을 반환

NumericText

문자열이 숫자이면 True 값 반환

ToNumber

문자열을 숫자로 변환

ToText

숫자를 문자열로 변환

ToWords

숫자를 단어로 변환

ReplicateString

인수로 지정한 값만큼 반복 프린트

Space

인수로 지정한 값만큼 공백문자 출력

Instr

문자열에서 다른 문자열의 위치를 반환

InstrRev

문자열에서 다른 문자열의 위치를 반대로 반환

StrCmp

문자열을 비교해서 결과값을 반환

Mid

문자열에서 지정한 만큼 문자열을 반환

Left

문자열의 좌측으로부터 지정된 수의 문자를 반환

Right

문자열의 우측으로부터 지정된 수의 문자를 반환

Val

문자값을 수치로 변환

Chr

아스키 값에 해당하는 문자 출력

Asc

지정한 문자의 아스키 값을 반환

Filter

Replace

Join

Split

함 수

기 능

Length

문자열 길이 변환

Trim

문자열 앞 뒤의 공백을 삭제

TrimLeft

문자열의 왼쪽 공백을 삭제

TrimRight

문자열의 오른쪽 공백을 삭제

UpperCase

문자열 데이터를 대문자로 변환

LowerCase

문자열 데이터를 소문자로 변환

StrReverse

뒤바뀌어진 문자열을 반환

NumericText

문자열이 숫자이면 True 값 반환

ToNumber

문자열을 숫자로 변환

ToText

숫자를 문자열로 변환

ToWords

숫자를 단어로 변환

ReplicateString

인수로 지정한 값만큼 반복 프린트

Space

인수로 지정한 값만큼 공백문자 출력

Instr

문자열에서 다른 문자열의 위치를 반환

InstrRev

문자열에서 다른 문자열의 위치를 반대로 반환

StrCmp

문자열을 비교해서 결과값을 반환

Mid

문자열에서 지정한 만큼 문자열을 반환

Left

문자열의 좌측으로부터 지정된 수의 문자를 반환

Right

문자열의 우측으로부터 지정된 수의 문자를 반환

Val

문자값을 수치로 변환

Chr

아스키 값에 해당하는 문자 출력

Asc

지정한 문자의 아스키 값을 반환

Filter

Replace

Join

Split

ex.CString a=Mid("miae",2)  a=>ae

a=Mid("miae",2,1) a=>a

 

CString a= "ppp.html";

Mid(a.ReverseFind('.')+1)   ==>  html

 

 

 

Find()

int Find( TCHAR ch ) const;

찾을 문자열을 인자로 전달받아 찾은 문자열의 위치정보를 int형의 값으로 리턴합니다

CString str = "abcde";

int n = str.Find('c'); // 요 경우는 2를 리턴합니다(문자열의 첫위치는0)

없는 문자열 'z'를 찾고자 할때는 음수값 -1을 리턴합니다

 

 

ReverseFind(x)

 

int ReverseFind( TCHAR ch ) const;

뒤에서 ch 문자를 찾아서 그 자리를 넘긴다.

CString s( "abcabc" );
int a = s.ReverseFind('b') =>  a=4가 된다.

두번째 a를 찾고자 할때는 다음과 같이 정의할 수 있습니다.

 

n = str.Find('a', 3); // 3의 위치는 d가 되므로 d의 위치부터 탐색을 시작하게 됩니다.

n = str.Find('a', str.Find('a',) + 1);

=>명확히 알 수 없는 경우,

 

 

Length(x)

x는 텍스트 문자열이거나 텍스트 문자열을 가진 필드입니다.

동작

텍스트 문자열이나 문자 데이터 필드의 길이를 반환합니다. 텍스트 문자열의 길이에 의한 조작, 비교, 계산 등에 사용됩니다.

예제

다음 수식에서 Account 문자열의 개수인 7이 반환됩니다.

Length("Account") = 7

다음 수식은 {table.개수} 필드의 값이 14233.08일 때입니다. ToText 함수로 수치를 문자열로 바꾼 다음에 계산하게 됩니다.

Length(ToText({table.개수})) = 8

숫자를 문자로 변환시키는 ToText 함수는 쉼표(또는 천단위 구분자)를 텍스트로 변환하지 않습니다. 숫자 14233.08은 "14233.08"이라는 문자열로 변환되어 문자 길이는 8이 됩니다.

Length("SMITH") = 5

다음 수식에서 BOB와 SMITH 사이의 공백도 문자로 세어집니다.

Length("BOB SMITH") = 9

Trim(x)

x는 문자열입니다.

동작

Trim은 문자열 앞, 뒤의 공백을 제거합니다.

TrimLeft(x)

x는 문자열이거나 오른쪽으로 정렬되어 저장된 데이터 필드입니다.

동작

TrimLeft는 문자열이나 데이터베이스에 오른쪽으로 정렬된 문자열로 저장된 데이터 필드 왼쪽의 모든 공백을 제거합니다.

예제

텍스트 문자열의 정렬, 문자 횟수, 또는 계산(만일 문자열이 결국 숫자로 변환된다면)을 방해하는 선행 공백이 있을 때 이 함수를 사용합니다.

TrimLeft(" Al/4520/B12") = "A1/4520/B12"

TrimRight(x)

x는 문자열이거나 오른쪽으로 정렬되어 저장된 데이터 필드.

동작

TrimRight는 문자열이나 데이터베이스에 왼쪽으로 정렬된 문자열로 저장된 데이터 필드의 오른쪽의 모든 공백을 제거합니다.

예제

텍스트 문자열의 정렬, 문자 횟수, 또는 계산(만일 문자열이 결국 숫자로 변환된다면)을 방해하는 후 행 공백이 있을 때 이 함수를 사용합니다.

TrimRight("Al/4520/B12 ") = "A1/4520/B12"

TrimRight({table.Reference}) = "Bal Fwd."

UpperCase(x)

x는 대문자로 변환하길 원하는 텍스트 문자열입니다.

동작

UpperCase는 텍스트 문자열을 대문자로 바꾸어줍니다. 대문자와 소문자로 이루어진 문자열에서 모든 문자를 대문자로 변환할 수 있습니다.

예제

UpperCase("Description") = "DESCRIPTION"

UpperCase("abc12345") = "ABC12345"

UpperCase("mr " + "bUtler" ) = "MR BUTLER"

LowerCase(x)

x는 데이터 필드에 있는 텍스트 값이거나 텍스트 문자열입니다.

동작

LowerCase는 소문자로 문자 데이터 필드나 텍스트 문자열을 소문자로 변환합니다. 이 함수는 필드가 대문자와 소문자 둘 다 포함하고 있고 일관성을 위해 모든 값을 소문자로 변환하고자 할 때입니다. 문자열 안의 숫자는 LowerCase 함수에 의해 영향을 받지 않습니다.

예제

LowerCase("Description") = "description"

LowerCase("BrEaD " + "AND " + "bUtTeR") = "bread and butter"

StrReverse(InputString)

동작

예제

NumericText(x)

x는 텍스트로 저장된 숫자를 포함하고 있는지를 검사하고자 하는 텍스트 필드입니다.

동작

NumericText는 텍스트 필드의 내용이 숫자인지를 검사합니다.

만일 필드의 전체 내용이 숫자이거나 subscript 연산자를 통해 추출된 문자가 전부 숫자이면 식은 YES 값을 반환합니다. 만일 필드 내용이나 추출된 문자의 일부가 숫자가 아니면 식은 값 NO를 반환합니다.

예제

만일 숫자가 저장된 텍스트 필드를 ToNumber를 사용하여 변환하기에 적당한 지를 확인하기 위해 NumericText를 사용할 수 있습니다.

If NumericText({table.고객코드}) = YES Then

ToNumber{table.고객코드}

ToNumber(x)

x는 텍스트 문자열로 저장된 숫자입니다

동작

ToNumber는 텍스트 문자열을 숫자로 변환합니다.

데이터베이스에서 어떤 숫자는 수치 필드에 숫자로 저장되고 어떤 것은 문자 필드에 텍스트로 저장됩니다. 사용자는 처음 데이터베이스를 설정할 때 필드를 숫자로 할 것인지 텍스트로 할 것인지 결정합니다. 사용자가 계산을 수행하게 될 숫자(항목 단가, 주문한 수량 등)는 일반적으로 수치 필드에 저장되고 계산을 수행하지 않을 숫자(고객번호, 전화번호 등)는 일반적으로 텍스트 필드에 저장됩니다.

예제

ToNumber는 텍스트로 저장된 숫자를 계산에 사용할 수 있는 숫자로 변환하도록 해줍니다. 예를 들면, 만일 항목 번호가 코드화된 제품 정보를 가지고 있고, 계산에 그 정보를 사용하고 싶을 경우 이 함수를 사용할 수 있습니다.

ToNumber("123.45") = 123.45

{table.고객점수} 필드가 문자이고 값이 21385일 때 다음 수식은 True를 반환합니다.

ToNumber({table.고객점수}) < 33333 = TRUE

ToText(x) / ToText(x, #places)

x는 텍스트로 변환되고자 하는 숫자이며 #places는 소수자리의 수를 지정하는 숫자입니다.

동작

ToText는 숫자를 텍스트 문자열로 변환합니다.

텍스트 문자열(폼 문자, 리포트의 주석, 플래그 등)에서 사용될 수 있도록 수치 필드값이나 숫자 계산의 결과를 텍스트로 변환하기 위해 이 함수를 사용할 수 있습니다.

ToText(x, # places)는 숫자를 텍스트 문자열로 변환하고 텍스트로 쓰여질 때 숫자의 소수자리의 수를 지정하도록 해줍니다.

예제

ToText(123.45) = "123.45"

ToText(12345.6749,2) = "12345.67"

ToText(12345.6750,2) = "12345.68"

ToText(12345.5000,0) = "12346"

ToWords(x) / ToWords(x, n)

x는 단어로 변환하고자 하는 숫자입니다. (1 = one, 68 = sixtyeight 등)

n은 결과의 포함된 소수자리의 수입니다.

동작

사용자는 텍스트로 사용될 수 있도록 숫자, 통화 필드값이나 숫자 계산의 결과를 단어로 변환하는데 이 함수를 사용합니다.

음수는 단어 "negative"로 시작합니다.

예제

ToWords(12345) = twelve thousand three hundred fortyfive and xx/100

ToWords(12345,0) = twelve thousand three hundred fortyfive

ToWords(12.3499) = twelve and 35/100

☞ 통화 필드값과 수치 필드값은 같은 방식으로 취급되고 동일한 결과를 산출합니다.

☞ 철자로 표현된 값이 숫자 값보다 훨씬 길기 때문에 새로운 필드 길이를 수용하기 위해 사용자는 필드 상자의 길이를 증가시킬 필요가 있습니다.

ReplicateString(x, n)

x는 문자열이고 n은 정수입니다.

동작

문자열 x를 n번 인쇄합니다. 간단한 막대 그래프를 *를 사용해서 작성하는 경우와 같이 문자열을 삽입하기 위해 이 함수를 사용합니다.

예제

조건에 맞으면 문자 "*" 를 10번 인쇄하는 수식은 다음과 같습니다.

If {table.목표액} < {table.실적} Then

ReplicateString("*",10)

Else

""

다음 수식은 고객점수 결과를 보여주는 막대 그래프를 인쇄합니다. 즉, 수식은 고객 점수 필드에 대해 별표를 인쇄합니다.

{table.고객이름}+ " " + ReplicateString("*", {table.고객점수})

Space(length)

length는 정수입니다.

동작

지정된 수의 공백으로 구성된 값을 반환합니다.

예제

다음 수식은 " "를 반환합니다.

Space(2)

InStr (str1, str2), InStr (start, str1, str2)

str1, str2는 문자열이고, start는 수치입니다.

동작

다른 문자열에서의 위치를 알려 줍니다. 위치를 지정하지 않으면 1이 지정된 것으로 동작됩니다. 만일 0이 반환되면 발견되지 않은 것입니다.

예제

다음 수식에서 2가 반환됩니다.

InStr("abcdefg", "bcd")

InStrRev(InputString)

동작

예제




StrCmp(str1, str2), StrCmp(str1, str2, compare)

str1, str2는 문자열이고 compare는 정수입니다.

동작

문자열 비교의 결과를 의미하는 값을 반환합니다.

str1이 str2 보다 적으면 -1

str1이str2와 같으면 0

str1이str2보다 크면 1

string1 또는 string2 이 Null이면 Null

예제

다음 수식은 1을 반환합니다.

StrCmp("abcd", "aa")

다음 수식은 -1을 반환합니다.

StrCmp ("abcd", "ac")

다음 수식은 0을 반환합니다.

StrCmp ("aa", "aa")

Mid(str, start), Mid(str, start, length)

str은 문자열, start와 length는 수치입니다.

동작

Mid 함수는 한 문자열에서 지정된 수의 문자들을 반환합니다.

예제

다음 수식은 "cd"를 반환합니다.

Mid("abcdef", 3, 2)

Left(str, length)

x는 텍스트 문자열입니다.

동작

지정한 수만큼 문자열의 앞 부분을 반환합니다.

예제

다음 수식에서 "abcd"가 반환됩니다.

Left("abcdefg", 4)

 

->)Mid()

CString Mid( int nFirst ) const;
throw( CMemoryException );

CString Mid( int nFirst, int nCount ) const;
throw( CMemoryException );

 

(예제)

CString stra ="aaaa<bcd>eeeeeeeeee"ff"g";

int nPoint=0, nNextPoint=0;

 

nPoint=stra.Find("<", nPoint);  //0 처음부터 < 있는걸 찾아서 그 자리 값을 nPoint에

 

stra.Mid(nPoint, 3); =><이후부터 3자리 찾으면, bcd 가 되겠졍~


Right(str, length)

str은 문자열이고 length는 정수입니다.

동작

문자열의 우측으로부터 지정된 수의 문자를 반환합니다.

예제

다음 수식은 "efg"를 반환합니다.

Right("abcdefg", 3)

Val(x)

x는 문자열입니다.

동작

Val 함수는 문자열을 수치로 바꾸어줍니다.

예제

다음 수식은 2234100을 반환합니다.

Val("2234 100th Street")

Chr(x)

x는 수치입니다.

동작

Asc 함수의 반대 동작을 합니다. 즉, 수치에 해당하는 문자를 반환합니다.

예제

다음 수식에서 아스키 값 65에 해당하는 A가 반환됩니다.

Chr(65)

ASC(x)

x는 텍스트 문자나 문자열입니다.

동작

텍스트 문자나 문자 데이터 필드의 첫 문자의 아스키 값을 반환합니다.

예제

다음 수식에서 문자 A의 아스키 값인 65가 반환됩니다.

Asc("A") = 65


'개발지식창고 > MFC' 카테고리의 다른 글

컨트롤의 색변환  (0) 2010.08.22
CString 사용예제  (0) 2010.08.17
■ CFile 클래스 : 파일 입출력 클래스  (0) 2010.07.30
WinMain.cpp를 MFC 클래스로 구현하면...  (0) 2010.07.30
MFC 내부에 감추어진 것들  (0) 2010.07.30
Posted by 모과이IT
,

printf의 마지막 f formatted(서식화된)를 의미한다.

 

    다양한 종류의 특수 문자

특수 문자

 

\a

경고음 소리 발생

\b

백스페이스(backspace)

\n

개행(한줄띄고 처음으로(캐리지 리턴)하는것을 말한다)

\r

캐리지리턴

\t

수평 탭

\v

수직 탭

\\

백슬래시(\)

\’

작은 따옴표

\”

큰 따옴표

 

서식 문자의 종류와 의미

서식 문자

출력 형태

%c

단일 문자

%d

부호 있는 10진 정수(int)

%s

문자열

%o

부호 없는 8진 정수

%u

부호 없는 10진 정수

%x

부호 없는 16진 정수, 소문자 사용

%X

부호 없는 16진 정수, 대문자 사용

%e

e 표기법에 의한 실수

%E

E 표기법에 의한 실수

%g

값에 따라 %f , %e 둘 중 하나를 선택

%G

값에 따라 %F , %E 둘 중 하나를 선택

%%

% 기호 출력(ex:3% -> %%d)

 

필드 폭

   출력되는 필드의 폭을 지정 할 수 있다.

서식 문자

출력의 형태

%8d

필드 폭을 8칸 확보하고 오른쪽 정렬해서 출력

%-8d

필드 폭을 8칸 확보하고 왼쪽 정렬해서 출력

%+8d

필드 폭을 8칸 확보하고 오른쪽 정렬한 상태에서 양수는 +, 음수는 ?를 붙여서 출력

 

'개발지식창고 > C' 카테고리의 다른 글

C 문자열 함수 정리  (0) 2010.09.20
BASE64 Encode/Decode  (0) 2010.09.20
문자열 처리 함수들  (0) 2010.08.22
32비트 배열을 이용한 상태값 저장 및 얻어오기  (0) 2010.08.16
[C/C++]#define 매크로 팁  (0) 2010.08.16
Posted by 모과이IT
,


[헤더 파일에 선인]
ULONG32 statusDropDownControl; // 동적인 컨트롤 상태를 담기위한 변수 초기화값은 0x00000000
enum
 {
  DROPDOWN_NONE   = 0x00000000, // 0000 0000 0000 0000 0000 0000 0000 0000
  DROPDOWN_COLOR   = 0x00000001, // 0000 0000 0000 0000 0000 0000 0000 0001
  DROPDOWN_SIZE   = 0x00000002, // 0000 0000 0000 0000 0000 0000 0000 0010
  DROPDOWN_FRONT   = 0x00000004, // 0000 0000 0000 0000 0000 0000 0000 0100
  DROPDOWN_FRAMECOLOR  = 0x00000008, // 0000 0000 0000 0000 0000 0000 0000 1000

  DROPDOWN_UPDATE1   = 0x00000010, // 0000 0000 0000 0000 0000 0000 0001 0000
  DROPDOWN_UPDATE2   = 0x00000020, // 0000 0000 0000 0000 0000 0000 0010 0000
  DROPDOWN_UPDATE3   = 0x00000040, // 0000 0000 0000 0000 0000 0000 0100 0000
  DROPDOWN_UPDATE4   = 0x00000080, // 0000 0000 0000 0000 0000 0000 1000 0000
 }; 

[실제 cpp 구현부분]

 * 상대 값들을 추가 할때
 statusDropDownControl |= DROPDOWN_COLOR;
 statusDropDownControl |= DROPDOWN_SIZE;
 statusDropDownControl |= DROPDOWN_FRONT;
 statusDropDownControl |= DROPDOWN_FRAMECOLOR;

* 해당 상태값을 얻을때
if(statusDropDown & DROPDOWN_COLOR)
 {
  ..

  retCount ++;
 }
 
 if(statusDropDown & DROPDOWN_SIZE)
 {
  // Size
  if(SalePriceDlgFormWnd->bb.hStatic[retCount] == NULL)
  ...
  retCount ++;
 }

 if(statusDropDown & DROPDOWN_FRONT)
 {
  // FRONT
  if(SalePriceDlgFormWnd->bb.hStatic[retCount] == NULL)
  ..
  retCount ++;
 }
 
 if(statusDropDown & DROPDOWN_FRAMECOLOR)
 {
  // FRAMECOLOR
  if(SalePriceDlgFormWnd->bb.hStatic[retCount] == NULL)
 ..
  retCount ++;
 }

'개발지식창고 > C' 카테고리의 다른 글

C 문자열 함수 정리  (0) 2010.09.20
BASE64 Encode/Decode  (0) 2010.09.20
문자열 처리 함수들  (0) 2010.08.22
printf 특수문자 출력하기  (0) 2010.08.16
[C/C++]#define 매크로 팁  (0) 2010.08.16
Posted by 모과이IT
,

C/C++ 에서 #define 을 사용을 가급적 자제하도록 권고되고 있지만, 잘 사용할 경우 많은 코딩상의 이득을 볼 수 있습니다.  

#define을 활용하는 예를 몇 가지 설명하려고 합니다.

 

우선 팁을 설명하기 전에 간단하게 ‘##’ “#’ 에 대해 살펴보고 가겠습니다. (샘플소스는 MSDN 에서 가져왔습니다)

 

1.     ‘##’ - Token-Pasting Operator (##): 분리되어 있는 2개의 토큰을 하나로 뭉쳐주는 역할을 합니다.

#define paster( n ) printf( "token" #n " = %d", token##n )


라고 할 때 아래와 같은 코딩은

int token9 = 9;

paster( 9 ); // token##n -> token 과실제인수9 를합쳐token9 가됨


다음과 같이 풀이되어 결국 ‘token9 = 9’ 가 화면에 표시되게 됩니다.

printf( "token" "9" " = %d", token9 );

printf( "token9 = %d", token9 );


이와 같이 ## 은 왼쪽 Operand 와 오른쪽 Operand를 접착제처럼 붙여 주는 역할을 합니다.

 

2.     ‘#’ - Stringizing Operator (#): 매크로 인자를 문자열로 만드는 역할을 합니다.

#define stringer( x ) printf( #x "\n" )


과 같이 정의 할 경우 아래와 같은 문장은

stringer( In quotes in the printf function call\n );


다음과 같이 풀어쓰게 됩니다.

printf( "In quotes in the printf function call\n" "\n" );

 

이제 #define 매크로를 이용한 활용예를 들어 보겠습니다.

1.    배열의 크기 구하기


#define 을 이용하는 가장 간단하고 자주 쓰이는 팁이 아닐까 생각됩니다.

#define arrayCnt( x ) sizeof(x) / sizeof(x[0])


 이를 이용한 간단 샘플입니다.

struct LIST_COL_DEF

{

           int nChar;

           char szText[20];

} ListCol[] =

{

           {20, "폴더"},

           {20, "파일명"}

};

for (int i = 0; i < arrayCnt(ListCol); i++)

{

           // To Do Something...

}

 

물론

i < arrayCnt(ListCol)

를 사용하지 않고

i < sizeof(ListCol) / sizeof(ListCol[0])

을 사용해도 되지만 이와 같은 작업을 여러 번 반복할 경우(array 를 사용하는 경우는 정말 흔하디 흔하죠) 단조로운 코딩이 반복될 수 있어 #define 을 이용한 매크로를 애용하고 있습니다.

 

2.    Get/Set 함수 간단하게 만들기

OOP(Object Oriented Programming)로 프로그램 할 경우 멤버 변수의 Get 함수와 Set 함수를 만들어야 할 경우가 많습니다. 변수를 외부로 드러내지 않고 변수에 대한 접근 Method 만 제공함으로써 추후 변경에 대한 유지보수를 최소화하기 위해 많이 사용하게 되는데요(OOP 의 특징 중에 하나인 Encapsulation). 간단한 Get/Set 함수라 하더라도 하드코딩일 경우 손이 많이 가게 됩니다. 이럴 경우 #define 매크로를 사용하면 단순반복적인 Get/Set 함수를 한 줄만으로 코딩하여 작성할 수 있습니다.


예를 들어 다음과 같은 매크로를 정의한 경우

// SIMPLE_FUNC_IMPL -> Get/Set 함수를자동으로만들어줍니다.

// 1. ret -> return type

// 2. fname -> Get/Set 다음에올함수명

// 3. var -> Get/Set 에대상이되는변수명

#define SIMPLE_FUNC_IMPL(ret, fname, var) \

           ret Get##fname() \

           { \

                     return var; \

           } \

           void Set##fname(ret tmp) \

           { \

                     var = tmp; \

           }

 

bool m_bTest Get 하고 Set 하는 간단한 함수는 아래 한 줄로 만들 수 있게 됩니다.

SIMPLE_FUNC_IMPL(bool, Test, m_bTest);


위 한 줄의 매크로는 자동으로 전 처리기에 의해 컴파일 시 다음과 같은 함수로 확장됩니다.

bool GetTest()

{

           return m_bTest;

}

void SetTest(bool tmp)

{

           m_bTest = tmp;

}


간단하지 않은가요 ^^.

외부로 공개해야 하는 속성이 많으면 많을수록 코딩부담을 줄이고, 미스타이핑으로 인한 오류를 사전에 막아 줄 수 있어 매크로는 더욱 위력을 발휘하게 됩니다.

사실 마이크로소프트의 ATL 3.0 라이브로리 소스 헤더를 분석해 보면 이와 같은 매크로를 훨씬 복잡하게 사용하고 있다는 걸 알 수 있습니다.

아래 샘플은 ATL 3.0 라이브러리 ATLCTL.H 소스에 있는 코드입니다. (소스가 길어 접습니다

 

소스코드 닫기

 

#define IMPLEMENT_STOCKPROP(type, fname, pname, dispid) \

           HRESULT STDMETHODCALLTYPE put_##fname(type pname) \

           { \

                     __if_exists(T::m_##pname) \

                     { \

                                ATLTRACE(ATL::atlTraceControls,2,_T("CStockPropImpl::put_%s\n"), #fname); \

                                T* pT = (T*) this; \

                                if (pT->m_nFreezeEvents == 0 && pT->FireOnRequestEdit(dispid) == S_FALSE) \

                                          return S_FALSE; \

                                pT->m_##pname = pname; \

                                pT->m_bRequiresSave = TRUE; \

                                if (pT->m_nFreezeEvents == 0) \

                                          pT->FireOnChanged(dispid); \

                                __if_exists(T::On##fname##Changed) \

                                { \

                                          pT->On##fname##Changed(); \

                                } \

                                pT->FireViewChange(); \

                                pT->SendOnDataChange(NULL); \

                     } \

                     return S_OK; \

           } \

           HRESULT STDMETHODCALLTYPE get_##fname(type* p##pname) \

           { \

                     __if_exists(T::m_##pname) \

                     { \

                                ATLTRACE(ATL::atlTraceControls,2,_T("CStockPropImpl::get_%s\n"), #fname); \

                                ATLASSERT(p##pname != NULL); \

                                if (p##pname == NULL) \

                                          return E_POINTER; \

                                T* pT = (T*) this; \

                                *p##pname = pT->m_##pname; \

                     } \

                     return S_OK; \

           }

소스코드 닫기

 

 끝으로, 이와 같은 #define 매크로의 단점도 잠시 언급하면

-       디버깅이 힘듭니다. 디버깅 시 매크로의 경우 확장된 소스가 보여지지 않아 변수의 변경사항을 추적해 들어 가기가 힘듭니다. 매크로가 복잡할 경우 애로가 있을 수 있어 복잡한 함수의 경우는 위와 같은 방식을 취하지 않는 편이 좋습니다.

-       #define MAX_CUSTOMER 10 보다는
const int MAX_CUSTOMER = 10
으로 코딩 하는 것이 변수가 잘못 typecasting 되는 걸 막을 수 있는 좋은 코딩 습관입니다. 사실 이 부분 때문에 #define 매크로사용을 자제해야 한다고 권장한다고 봐야겠죠.

 

이상으로 #define 매크로에 대해 아주 간단한 팁을 알아봤습니다. 사실 초보자가 아닌 경우 대부분 아실 만한 내용이라 적기가 부끄러운 내용이긴 한데 기록해 둘 경우 나중에 기억이 가물가물해 졌을 때나, 프로그램을 시작하는 다른 분들에게 도움이 될까 하고 적어봤습니다. 오늘도 열코!!

'개발지식창고 > C' 카테고리의 다른 글

C 문자열 함수 정리  (0) 2010.09.20
BASE64 Encode/Decode  (0) 2010.09.20
문자열 처리 함수들  (0) 2010.08.22
printf 특수문자 출력하기  (0) 2010.08.16
32비트 배열을 이용한 상태값 저장 및 얻어오기  (0) 2010.08.16
Posted by 모과이IT
,

No_Excuses
May 24th, 2002, 07:10 PM
I have created a simple project using the wizard. It is a simple dialog and which has ok and cancel buttons. When I exit everything is ok (when you look into the output window (The program '[1472] test1.exe: Native' has exited with code 0 (0x0).).

Note the code snippet for the "ok" run:

CInternetSession m_session;
CStdioFile *m_pfile;

#if 0
m_pfile = m_session.OpenURL("http://www.codeguru.com");
if (m_pfile != NULL)
m_session.Close();
#endif

I then commented out the #if/endif as follows:

CInternetSession m_session;
CStdioFile *m_pfile;

//#if 0
m_pfile = m_session.OpenURL("http://www.codeguru.com");
if (m_pfile != NULL)
m_session.Close();
//#endif

The following is seen in the output window:

Detected memory leaks!
Dumping objects ->
{83} normal block at 0x002F7BC8, 20 bytes long.
Data: < .| > 10 FF 2E 7C 03 00 00 00 03 00 00 00 01 00 00 00
{82} normal block at 0x002F7B78, 18 bytes long.
Data: < .| > 10 FF 2E 7C 01 00 00 00 01 00 00 00 01 00 00 00
{81} normal block at 0x002F7B18, 33 bytes long.
Data: < .| > 10 FF 2E 7C 10 00 00 00 10 00 00 00 01 00 00 00
{80} normal block at 0x002F2A60, 18 bytes long.
Data: < .| > 10 FF 2E 7C 01 00 00 00 01 00 00 00 01 00 00 00
inet.cpp(560) : {79} client block at 0x002F7A90, subtype c0, 76 bytes long.
a CHttpFile object at $002F7A90, 76 bytes long
Object dump complete.
The program '[1460] test1.exe: Native' has exited with code 0 (0x0).

I have searched quite a bit for others with this same problem and have seen people ask for an answer but they never got one.

Here are my questions:

1) Can something be done to fix the memory leak and if the answer is yes what is it?

2) All I do is read the html from the specified URL (not included in my simple example/test above). If there is a better alternative would you please suggest it and if possible give a simple example or reference as to where I can go to view the solution.

Thanks in advance,

Todd G.

NigelQ
May 24th, 2002, 07:32 PM
This should remove the memory leak...


CInternetSession m_session;
CStdioFile *m_pfile;

//#if 0
m_pfile = m_session.OpenURL("http://www.codeguru.com");
if (m_pfile != NULL)
{
m_pfile->Close();
delete m_pfile;
}
m_session.Close();
//#endif


Hope this helps,

- Nigel

No_Excuses
May 24th, 2002, 07:41 PM
Thanks for the response!!! It does eliminate the memory leak.

I do get the following warning:

Warning: destroying an open CInternetFile with handle 00CC000C

I tried putting the delete before and after the close session and got the same warning either way.

{
m_session.Close();
delete m_pfile;
}

and

{
m_session.Close();
delete m_pfile;
}

Any other comments to eliminate this warning?

Thanks in advance,

Todd G.

NigelQ
May 24th, 2002, 07:43 PM
I edited the snippet of code (not before you saw it, it seems). Try the new version above.

- Nigel

No_Excuses
May 24th, 2002, 07:47 PM
Thanks for you quick reply!! No more leaks or warnings!

Todd G.


** New로 선언되어지고 delete를 다 해주었는데.. memory leak이 발생하여 걱정하였는데
    구글에서 찾아보니..... 해결점을 찾았다. 문제는 CHttpfile로 포인터형으로 인스턴스 형으로 선언되어진것을
     delete 해주니까 해결이 되었다 -.-;;;
Posted by 모과이IT
,

ActiveX를 만들었는데, 레지스트리나 시스템 파일 등...의 기능이 포함되어 있을 경우,

" 이 페이지의 ActiveX 컨트롤이 다른 부분과 상호 작용하는데 안전하지 않을 수 있습니다.

상호 작용을 허용하시겠습니까? "

와 같은 메시지가 뜨게 됩니다.

 

이 경우,

아래와 같이 안정성 처리(IObjectSafety)를 추가해줘야 합니다.

 

1. Ctrl 클래스의 헤더파일(h)에 추가해줍니다.

 

    : 색으로 표시된 부분 과감히 CTRL+C, CTRL+V 하시면 됩니다. ^^;... (MS 문서 참조)

#include <objsafe.h>

class CTestCtrl : public COleControl
{
 //////////////////////////////////////////////////////////////////////////
 // EOCS_2010_0217 : IObjectSafety 처리 추가
 DECLARE_INTERFACE_MAP()
       
  BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)
        STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) (
        /* [in] */ REFIID riid,
        /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
        /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions
        );
   
    STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) (
        /* [in] */ REFIID riid,
        /* [in] */ DWORD dwOptionSetMask,
        /* [in] */ DWORD dwEnabledOptions
        );
    END_INTERFACE_PART(ObjSafe);

// Constructor
public:

.

.

.

2. Ctrl 클래스의 소스파일(cpp)에 추가해줍니다.

 

    : 색으로 표시된 부분 과감히 CTRL+C, CTRL+V 하시면 됩니다. ^^;... (MS 문서 참조)

      . MS 자료나 인터넷이나 다 이렇게 정형화(?) 되어 있습니다.

/////////////////////////////////////////////////////////////
// Interface map for IObjectSafety

BEGIN_INTERFACE_MAP( CTestCtrl, COleControl )
INTERFACE_PART(CTestCtrl, IID_IObjectSafety, ObjSafe)
END_INTERFACE_MAP()

/////////////////////////////////////////////////////////////
// IObjectSafety member functions

ULONG FAR EXPORT CTestCtrl::XObjSafe::AddRef()
{
    METHOD_PROLOGUE(CTestCtrl, ObjSafe)
        return pThis->ExternalAddRef();
}

ULONG FAR EXPORT CTestCtrl::XObjSafe::Release()
{
    METHOD_PROLOGUE(CTestCtrl, ObjSafe)
        return pThis->ExternalRelease();
}

HRESULT FAR EXPORT CTestCtrl::XObjSafe::QueryInterface(
                 REFIID iid, void FAR* FAR* ppvObj)
{
    METHOD_PROLOGUE(CTestCtrl, ObjSafe)
        return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}

const DWORD dwSupportedBits =
INTERFACESAFE_FOR_UNTRUSTED_CALLER |
INTERFACESAFE_FOR_UNTRUSTED_DATA;
const DWORD dwNotSupportedBits = ~ dwSupportedBits;

HRESULT STDMETHODCALLTYPE
CTestCtrl::XObjSafe::GetInterfaceSafetyOptions(
               /* [in] */ REFIID riid,
               /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
               /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)
{
    METHOD_PROLOGUE(CTestCtrl, ObjSafe)
       
        HRESULT retval = ResultFromScode(S_OK);
   
    // does interface exist?
    IUnknown FAR* punkInterface;
    retval = pThis->ExternalQueryInterface(&riid,
        (void * *)&punkInterface);
    if (retval != E_NOINTERFACE) {  // interface exists
        punkInterface->Release(); // release it--just checking!
    }
   
    // we support both kinds of safety and have always both set,
    // regardless of interface
    *pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits;
   
    return retval; // E_NOINTERFACE if QI failed
}

HRESULT STDMETHODCALLTYPE
CTestCtrl::XObjSafe::SetInterfaceSafetyOptions(
               /* [in] */ REFIID riid,
               /* [in] */ DWORD dwOptionSetMask,
               /* [in] */ DWORD dwEnabledOptions)
{
    METHOD_PROLOGUE(CTestCtrl, ObjSafe)
       
        // does interface exist?
        IUnknown FAR* punkInterface;
    pThis->ExternalQueryInterface(&riid,
        (void**)&punkInterface);
    if (punkInterface) {    // interface exists
        punkInterface->Release(); // release it--just checking!
    }
    else { // interface doesn't exist
        return ResultFromScode(E_NOINTERFACE);
    }
   
    // can't set bits we don't support
    if (dwOptionSetMask & dwNotSupportedBits) {
        return ResultFromScode(E_FAIL);
    }
   
    // can't set bits we do support to zero
    dwEnabledOptions &= dwSupportedBits;
    // (we already know there are no extra bits in mask )
    if ((dwOptionSetMask & dwEnabledOptions) !=
        dwOptionSetMask) {
        return ResultFromScode(E_FAIL);
    }                              
   
    // don't need to change anything since we're always safe
    return ResultFromScode(S_OK);
}

 

Posted by 모과이IT
,