'공부/프로그램'에 해당되는 글 31건
- 2013.08.07 URLDownloadToFile로 파일 다운시 캐시로 인한 갱신 오류 방지
- 2013.08.07 관리자 권한 실행 확인 및 아닐 경우 처리
- 2013.08.05 권한상승을 위해 실행파일에 manifest 추가(펌)
- 2013.02.01 외부 프로그램 실행 3
- 2013.01.24 CPU 점유율 계산 1
- 2012.10.23 SVN 기존 commit comment 수정하기 2
- 2012.07.06 VLD(Visual Leak Detector)를 통한 메모리 릭 찾기 1
- 2012.05.25 HLSL Intrinsic Functions 1
- 2010.11.16 HSB, YUV 2
- 2010.09.27 MessageBox 일정 시간 후에 사라지게 하기 2
관리자 권한 실행 확인 및 아닐 경우 처리
if(IsUserAnAdmin())
{
// 관리자 권한으로 실행중
}
else
{
// 아닐 경우 관리자 권한으로 프로그램 실행
SHELLEXECUTEINFO si;
ZeroMemory(&si, sizeof(SHELLEXECUTEINFO));
si.cbSize = sizeof(SHELLEXECUTEINFO);
si.hwnd = NULL;
si.fMask = SEE_MASK_FLAG_DDEWAIT;
si.lpVerb = "runas";
si.lpFile = "Launcher.exe";
si.lpParameters = lpCmdLine;
si.nShow = SW_SHOWNORMAL;
si.lpDirectory = 0;
ShellExecuteEx(&si);
exit(0);
}
권한상승을 위해 실행파일에 manifest 추가(펌)
Administrators 권한이 있는 경우에만 정상적으로 수행될 수 있는 어플리케이션을 만들기 위해서는 manifest를 이용하여 '이 프로그램을 수행하기 위해서는 반드시 권한상승이 필요하다'는 정보를 실행파일에 포함시킬 필요가 있습니다.
물론, 오른마우스를 클릭해서 "관리자 권한으로 실행" 으로 어플리케이션을 수행하거나, '속성'에서 '관리자 권한으로 이 프로그램 실행'을 선택할 수도 있겠지만, 사용자에게 이렇게 어플리케이션을 수행할 것을 강요하는 것은 매우 어려운 일이기 때문에, 실행파일 자체에 '이 어플리케이션은 반드시 Administrators permission이 필요하다' 라는 정보를 추가하여, 자동적으로 권한상승 창이 뜰 수 있도록 하는 것은 매우 중요합니다. 그런데 Visual Studio 2005 조차도 이러한 정보를 단숨에 실행파일에 추가하는 손쉬운 방법을 제공하지는 않습니다. (1. 아래 내용을 보면 아시겠지만 그렇다고 매우 복잡한것도 아닙니다. 2. 한편으로 보면 이는 매우 당연합니다. Visual Studio 2005가 Vista보다 미리 출시되었을 뿐더러 이러한 manifest를 추가하는 것은 단순히 특수한 type의 resource를 추가하는 것 이상의 동작이 아니기 때문입니다.) 게다가 managed code를 개발하느냐 혹은 C/C++와 같이 native code를 개발하느냐에 따라 그 방법이 서로 상이하기 때문에 조금은 혼돈스러울 수 있습니다.
앞서 말한 이러한 제약사항(본 어플리케이션은 반드시 Administrators 권한이 필요하다와 같은)은 manifest 라는 파일에 기록되게 되며, manifest 파일들은 실행파일에 추가(embedding)될 수 있습니다. manifest 파일의 일반적인 구조는 다음과 같습니다. 이 파일은 '실행파일명.exe.manifest' 라는 파일로 저장하는 것이 좋습니다. 'MyApp.exe'가 실행파일명이라면 'MyApp.exe.manifest'로 저장하시면 됩니다.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0"
processorArchitecture="X86"
name="IsUserAdmin"
type="win32"/><description>Description of your application</description>
<!-- Identify the application security requirements. -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="requireAdministrator"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>(indentation을 못해서 죄송합니다. 어떻게 하는지를 모르겠어요 ^^;)
이제 실질적인 3가지 절차를 알아 봅시다.
1. 'Step by Step' 방법
먼저 '실행파일명.rc' 라는 이름의 빈파일을 만듭니다. 'MyApp.rc'와 같이 만들면 됩니다. 아래와 같은 내용을 적습니다.
#define RT_MANIFEST 24
#define APP_MANIFEST 1APP_MANIFEST RT_MANIFEST MyApp.exe.manifest
위 의미는 RT_MANIFEST 형 resource로 APP_MANIFEST 라는 이름의 identifier를 "MyApp.exe.manifest" 라는 내용을 정의한다라는 의미입니다.(manifest 형 resource 구분자의 값은 항상 1로 정의하는 것이 좋습니다.
(참고적으로 파일내에 RT_MANIFEST 를 정의하는 대신 #include <winuser.h> 를 포함시키는 것도 좋은 방법입니다. 하지만 이 경우 winuser.h 파일의 위치를 정의하기 위하여 추가적인 명령들을 설정해야할 수 있습니다. 또한 MyApp.exe.manifest 파일을 rc 파일과 분리된 파일로 두지 않고 rc 파일내에 쓸 수도 있습니다.)
이제 rc 파일을 컴파일하여 res 파일을 만듭니다. 컴파일 하는 방법은 다음과 같은 두가지 방법 중 한가지를 사용하면 됩니다.
- command line prompt 에서 rc.exe /r MyApp.rc 를 입력합니다.
- Visual Studio 2005 내에서 project properties를 선택하고 Build Event Tab의 Pre-Build event에 다음을 입력합니다.
"$(DevEnvDir)..\..\SDK\v2.0\bin\rc.exe" /r "$(ProjectDir)$(TargetName).rc"
(rc.exe 파일의 위치는 적절히 수정되어야할 수 있습니다.)
이제 컴파일된 resource를 실행파일에 추가하기 위한 절차를 수행합니다. 다음과 같은 2가지 방법이 있을 수 있습니다.
- Visual Studio 2005나 MsBuild를 이용하는 방법
MyApp.csproj 파일을 열어서 볼드체로 표시된 내용을 다음과 같이 추가합니다.
<PropertyGroup>
...
<Win32Resource>MyApp.res</Win32Resource>...
</PropertyGroup>
- command line을 이용하여 컴파일 하는 방법
csc /win32res:MyApp.res MyApp.cs
vjc /win32res:MyApp.res MyApp.jsl
vbc /win32resource:MyApp.res MyApp.vb
2. mt.exe를 활용하는 방법
mt.exe 를 이용하면 이미 생성된 실행파일에 manifest 파일을 embedding할 수 있습니다. mt.exe를 활용하는 방법에도 2가지 방법이 있을 수 있습니다.
- command prompt를 이용하여 다음과 같이 입력합니다.
mt.exe -manifest MyApp.exe.manifest -outputresource:MyApp.exe;#1
여기서 #1 은 manfest 파일에 대한 resource identifier를 1로 정의한다는 의미입니다.
- Visual Studio 2005 내에서 project properties를 선택하고 Build Event Tab의 Post-Build event에 다음을 입력합니다.
"$(DevEnvDir)..\..\VC\bin\mt.exe" -manifest "$(ProjectDir)$(TargetName).exe.manifest" –outputresource:"$(TargetDir)$(TargetFileName)";#1
3. Manifest Tool을 이용하는 방법
Visual Studio 2005를 이용하여 C++ 어플리케이션을 개발하고 있다면, 좀 더 손쉽게 manifest 파일을 embedding할 수 있습니다.
project properties를 선택하고 Configuration Properties->Manifest Tool을 선택한 후, Input and Output을 선택합니다. Additional Manifest Files 에 'MyApp.exe.manifest' 와 같이 manifest 파일명을 입력하면 됩니다.
결론
이러한 3가지 방법중에 각각 선호하는 방법을 선택하면 되겠습니다만, 2번 방법을 이용하는 것이 가장 간단하면서도, managed/native의 구분없이 사용할 수 있으므로 가장 적절하지 않을까 생각됩니다.
다음 Link를 참고하십시오.
Developer Best Practices and Guidelines for Applications in a Least Privileged Environment
.Net Security Blog : Adding a UAC Manifest to Managed Code
The Moth: Vista: User Account Control
How To: Tell Vista's UAC What Privelege Level Your App Requires
외부 프로그램 실행
1. 현재 프로세스 종료 안시키고 실행
SHELLEXECUTEINFO si;
ZeroMemory(&si, sizeof(si));
si.cbSize = sizeof(si);
si.lpFile = 실행파일명;
si.lpDirectory = 실행파일 경로;
si.nShow |= SW_SHOWNA;
si.lpParameters = (LPCSTR)보내고자할 파라미터 데이터;
if(!ShellExecuteEx(&si))
{
int res = GetLastError();
if(res == ERROR_FILE_NOT_FOUND)
AfxMessageBox("프로그램을 찾을 수 없습니다.");
if(res == ERROR_PATH_NOT_FOUND)
AfxMessageBox("프로그램 경로가 올바르지 않습니다.");
if(res == ERROR_ACCESS_DENIED)
AfxMessageBox("프로그램 액세스가 거부되었습니다.");
return;
}
2. 현재 프로세스 종료시키고 실행
- 기존 프로세스의 기억 공간에 새로운 프로그램을 적재함으로써, 호출 프로세스를 변형(프로세스 식별번호 유지)
- 테스트 해보니 클래스의 소멸자 호출이 되지 않음(메모리 릭 발생 가능성 존재)
execl (char*path, char*argo, char*arg1,………,NULL)
execv (char*path, char**argv)
execlp(char*filename, char*argo, char*arg1,………,NULL)
execvp(char*filename, char**argv)
path 실행화일이 있는 곳까지의 전체 경로 이름
argo 실행하고자 하는 프로그램 이름
arg1~argn 실행하고자 하는 프로그램의 인수들
avgv 실행하고자 하는 프로그램의 인수들의 배열
filename 실행하고자 하는 프로그램 이름
[출처] execl, execv 함수 사용법|작성자 지코
참조
http://blog.naver.com/PostView.nhn?blogId=eyes0311&logNo=20009947817&redirect=Dlog&widgetTypeCall=true
http://blog.naver.com/PostView.nhn?blogId=shymusicko&logNo=90005695640
[출처] 외부프로그램 실행하기|작성자 아이즈
CPU 점유율 계산
현재 사용되는 프로세스의 CPU 점유율 계산법
double XfGetTime(void)
{
LARGE_INTEGER liEndCounter,liFrequency ;
QueryPerformanceCounter(&liEndCounter);
QueryPerformanceFrequency(&liFrequency);
return (liEndCounter.QuadPart / (double)liFrequency.QuadPart) * 1000;
}
bool GetCpuShare(double &dShare) { static double oldTime = XfGetTime(); //start 상태의 가장 마지막 값을 저장한다. static __int64 iOldKernelTime=0, iOldUserTime=0; LARGE_INTEGER iCreationTime, iExitTime, iKernelTime, iUserTime; bool ret = false; if( GetProcessTimes( GetCurrentProcess() , (LPFILETIME) &iCreationTime, (LPFILETIME) &iExitTime , (LPFILETIME) &iKernelTime, (LPFILETIME) &iUserTime ) == TRUE ) { if( iOldKernelTime > 0) { __int64 sum = iKernelTime.QuadPart - iOldKernelTime + iUserTime.QuadPart - iOldUserTime; sum /= 10000; // 100 nano sec 단위에서 msec 단위로 변환 if( XfGetTime() - oldTime > 0) { dShare = sum / (XfGetTime()-oldTime) * 100.0 ; ret = true; } } iOldKernelTime = iKernelTime.QuadPart; iOldUserTime = iUserTime.QuadPart; oldTime = XfGetTime(); } return ret; }
인터넷에서 찾다보니 위와 같은 함수가 있어서 사용했는데 이상한 결과가 나오는 걸 확인했다
최종 값에 아래의 값을 가져와서 나누면 제대로된 결과가 나오는 거 같다.
(Processor 갯수만큼 나눠서 사용한다는 소리)
SYSTEM_INFO Info;
GetSystemInfo(&Info);
dShare /= Info.dwNumberOfProcessors;
참조 : http://ictlab.tistory.com/24
SVN 기존 commit comment 수정하기
windows
- 해당하는 SVN 저장소의 hooks 디렉토리에 pre-revprop-change.bat 라는 파일을 생성
ex) Repositories/sample_project/hooks/pre-revprop-change.bat
- pre-revprop-change.bat 파일내용
if "%4" == "svn:log" exit 0
echo Changing revision property '%4' is prohibited >&2
exit 1
unix
- 파일명을 pre-revprop-change
hooks 디렉토리 밑에 pre-revprop-change.tmpl 에 예제참조.
VLD(Visual Leak Detector)를 통한 메모리 릭 찾기
Visual Studio 에서 제공해주는 CRT debug library와는 다르게 callstack을 보여준다는 장점이 있다.
아래 사이트에서 다운 받아서 사용하면 된다.
셋팅
- predefined header, 즉 stdafx.h 뒤에 vld.h 를 포함
- 프로젝트 속성에서 include와 lib 위치 추가
셋팅된 프로젝트에서만 Leak이 검출 되기 때문에 DLL을 사용하던가 다른 프로젝트가 존재하는 경우 해당 프로젝트도 같은 셋팅을 해야한다.
추가 사항
- 파일로 남기고 싶을 경우 설치 폴더에 있는 vld.ini파일에서 ReportTo 옵션을 file 또는 both를 변경
HLSL Intrinsic Functions
abs: 절대값을 구한다.
acos: 코사인에 대한 역 삼각함수
all(x); x의 모든 원소가 0인가? 맞으면 true, 아니면 false를 리턴한다.
any(x): x의 원소중에 0이 아닌 원소가 하나라도 있는가? 있으면 true, 없으면 false를 리턴한다.
asfloat: 인자값을 float 타입으로 바꾼다.
asin: 싸인에 대한 역 삼각함수
asint: 인자값을 int 타입으로 바꾼다.
asuint: 인자값을 uint 타입으로 바꾼다.
atan: 탄젠트에 대한 역 삼각함수
atan2: atan2(y,x) 의 형태로 쓰이며 이는 atan(y/x)와 같다. 분모인 x는 당연히 0이어서는 안 된다.
ceil: 인자값으로 전달 받은 float형 값보다 크거나 같은 정수들 중에서 가장 작은 값
clamp: 인자값을 특정 범위로 한정한다. 즉, clamp(x, min, max)에서 x가 min보다 작으면 min을
max보다 크면 max를 리턴한다.
clip:
픽셀 쉐이더에서만 사용 가능하다. 만약 인자값이 0보다 작으면 현재의 픽셀을 버린다.
clip( Input.Color.A < 0.1f ? -1:1 );
위에서 만약 알파값이 0.1보다 작다면 인자값은 -1이 될 것이고 이는 0보다 작기 때문에
해당 픽셀은 처리되지 않게 된다.
cos, sin, tan: 기본 삼각함수
cross: 인자로 받은 두 개의 float형 3D 벡터값들의 외적값을 구한다.
D3DCOLORtoUBYTE4: D3DCOLOR값으로 채워진 4D 벡터의 float형 성분들을 UBYTE4 형으로 변경한다. UBYTE4형을 지원하지
않는 특정 하드웨어를 위해 마련된 함수이다.
ddx: ddx_coarse 참조
ddy: ddy_coarse 참조
degrees: 인자로 입력 받은 라디언 값에 해당하는 degree값을 리턴한다.
determinant: 인자로 입력받은 정방행렬의 행렬식을 구한다.
distance(x,y): 두 벡터의 거리를 구한다.
dot: 인자로 받은 두 개의 3D 벡터들의 내적값을 구한다.
log: 밑이 e인 로그값을 구한다.
log10: 밑이 10인 로그값을 구한다.
log2: 밑이 2인 로그값을 구한다.
floor:인자값으로 전달 받은 float형 값보다 작거나 같은 정수들 중에서 가장 큰 값
radians: 인자로 입력 받은 degree 값에 해당하는 radian값을 리턴한다.
sqrt(x) : x의 제곱근을 구한다.
rsqrt: 제곱근의 역수를 구한다.
max: 두 인자 중 큰 값을 구한다.
min: 두 인자 중 작은 값을 구한다.
fwidth:
isfinite(x): x가 유한한가? 맞으면 true, 아니면 false 리턴
isinf(x): x가 무한인가? 맞으면 true, 아니면 false 리턴
length(x): 벡터 x 의 길이를 리턴
normalize: 정규화한다.
pow(x,y): x^y, 즉 x의 y승 값을 리턴
exp(x): 밑을 e로 하는 지수 e^x를 리턴
exp2(x): 밑을 2로 하는 지수 2^x를 리턴
modf(x,i) : x의 정수부분은 i에 저장되고 소수점 이하부분이 리턴값으로 넘어온다.
sign(x) : x의 부호를 리턴한다. 부호가 음수이면 -1, 0이면 0, 양수이면 1을 리턴
saturate(x) : x를 [0, 1] 범위의 값으로 한전한다
lerp(x,y,s) : 선형보간 값인 x + s(y - x) 를 리턴한다.
step(x,y) : x가 y보다 작거나 같은지 판단한다. 맞으면 1, 그렇지 않으면 0을 리턴한다
smoothstep(min,max,x) : x가 [min, max] 사이의 값인 경우에 [0, 1] 사이의 Hermite 보간 값을
리턴한다.
fmod(x,y) : x/y의 나머지 값을 리턴한다
frac(x) : x의 소수점 이하 부분을 리턴한다
frexp(x,e) : 주어진 실수 x의 소수점 이하값인 가수부분과 지수부분을 동시에 리턴한다.
가수부분을 e로 리턴하고, 지수부분을 함수리턴값으로 리턴한다
round(x) : 반올림한 정수를 리턴
mul(x,y) : 두 행렬의 곱을 리턴한다.
faceforward(n, i, ng) : 관찰자를 향하는 표면 노말값을 리턴한다
reflect(i, n) : 반사벡터를 리턴한다.
refract(i, n, R) : 굴절벡터를 리턴한다.
lit(n·l, n·h, m) : 조명계수 벡터를 리턴한다.
noise(x) : Perlin 노이즈값을 리턴한다.
fwidth(x): abs(ddx(x)) + abs(ddy(x)) 를 계산한다.
cosh(x): x의 cosine hyperbolic(쌍곡 함수) 값을 얻는다.
sinh(x): x의 sine쌍곡 함수 값을 얻는다.
tanh(x): x의 tangent쌍곡 함수 값을 얻는다.
sincos(x, out sineVal, out cosVal): x에 대한 sine값을 구해 sineVal에 저장하고, cosine값은 cosVal에 저장한다.
GetRenderTargetSampleCount: 렌더 타겟에 대한 샘플 갯수를 구한다.
GetRenderTargetSamplePosition(index) 인덱스에 해당하는 샘플에 대해서 샘플링 위치를 구한다.
isnan(x): x가 NAN(Not a number) 이거나 QNAN(Quiet Not a number)인지 판단한다.
ldexp(x, exp): x * (2의 exp 승)을 계산한다.
tex1D(s, t) : 샘플러 s를 이용 t 위치에서 텍스쳐의 색깔 정보를 뽑아낸다. 쉐이더가 1D를 지원하지 않기 때문에
컴파일러는 2D 텍스쳐를 사용하게 되는데, 대신 컴파일러는 y좌표는 중요하지 않다고 판단한다.
tex1D(s, t, ddx, ddy): 어떤 mip 단계를 선택할지 ddx와 ddy를 가지고 판단하고, 샘플러 s를 이용해
t에서의 색깔 정보를 뽑아낸다.
tex1Dbias(s,t): bias는 Vertex Shader에서는 사용할 수 없고 Pixel Shader에서만 사용할 수 있다. t.w에 의해 mip map
level을 정한 후 샘플러 s를 이용 해당 픽셀의 색깔 정보를 얻는다.
이미지를 흐리게 보이게 하거나 선명하게 보이게 하게 위해 쓰일 수 있다.
tex1Dgrad(s, t, ddx, ddy): 어떤 mip 단계를 선택할지 x와 y의 gradient 정도값을 이용하고, 샘플러 s를 이용해
t에서의 색깔 정보를 뽑아낸다.
tex1Dlod(s,t): t.w에 의해 miplevel을 정한 후 샘플러 s를 이용 해당 픽셀의 색깔 정보를 얻는다. t.w에 의해 LOD가
어느단계에서 변할지를 결정한다.
tex1Dproj: proj 가 붙으면 t.w 값에 의해 texture 좌표값 각각이 나뉘게(/) 된다.
tex2D(s, t): 샘플러 s를 이용해 2D 텍스쳐의 색깔 정보를 얻어낸다.
tex2D(s, t, ddx, ddy): 샘플러 s를 이용해 2D 텍스쳐 t에서의 색깔 정보를 얻어낸다. ddx와 ddy를 이용해 mipmap level을 정한다.
tex2Dbias(s,t): t.w에 의해 mip map level을 정한 후 샘플러 s를 이용 2D 텍스쳐의 픽셀 색깔 정보를 얻는다.
tex2Dgrad(s, t, ddx, ddy): 어떤 mip 단계를 선택할지 ddx와 ddy를 통해 결정하고, 샘플러 s를 이용해 2D 텍스쳐
t에서의 색깔 정보를 뽑아낸다.
tex2Dlod(s,t): t.w에 의해 mip map level을 정한 후 샘플러 s를 이용 2D 텍스쳐의 픽셀 정보를 얻는다. t.w에 의해 LOD가
어느단계에서 변할지를 결정한다.
tex2Dproj(s,t): 2D 텍스쳐에서 샘플러 s를 이용해 샘플링을 한다. 이때 t.w 값에 의해 texture 좌표값 각각이 나뉘게(/) 된다.
tex3D(s, t): 샘플러 s를 이용해 3D 텍스쳐의 색깔 정보를 얻어낸다.
tex3D(s, t, ddx, ddy): 샘플러 s를 이용해 3D 텍스쳐 t에서의 색깔 정보를 얻어낸다. ddx와 ddy를 이용해 mipmap level을 정한다.
tex3Dbias(s,t): t.w에 의해 mip map level을 정한 후 샘플러 s를 이용 3D 텍스쳐의 픽셀 색깔 정보를 얻는다.
tex3Dgrad(s, t, ddx, ddy): 어떤 mip 단계를 선택할지 ddx와 ddy를 통해 결정하고, 샘플러 s를 이용해 3D 텍스쳐
t에서의 색깔 정보를 뽑아낸다.
tex3Dlod(s,t): t.w에 의해 mip map level을 정한 후 샘플러 s를 이용 3D 텍스쳐의 픽셀 정보를 얻는다. t.w에 의해 LOD가
어느단계에서 변할지를 결정한다.
tex3Dproj(s,t): 3D 텍스쳐에서 샘플러 s를 이용해 샘플링을 한다. 이때 t.w 값에 의해 texture 좌표값 각각이 나뉘게(/) 된다.
texCUBE(s, t)샘플러 s를 이용해 큐브 텍스쳐의 색깔 정보를 얻어낸다.
texCUBE(s, t, ddx, ddy): 샘플러 s를 이용해 큐브 텍스쳐 t에서의 색깔 정보를 얻어낸다.
ddx와 ddy를 이용해 mipmap level을 정한다.
texCUBEbias(s,t): t.w에 의해 mip map level을 정한 후 샘플러 s를 이용 큐브 텍스쳐의 픽셀 색깔 정보를 얻는다.
texCUBEgrad(s, t, ddx, ddy): 어떤 mip 단계를 선택할지 ddx와 ddy를 통해 결정하고, 샘플러 s를 이용해 큐브 텍스쳐
t에서의 색깔 정보를 뽑아낸다.
texCUBElod(s,t): t.w에 의해 mip map level을 정한 후 샘플러 s를 이용 큐브 텍스쳐의 픽셀 정보를 얻는다. t.w에 의해 LOD가
어느단계에서 변할지를 결정한다.
texCUBEproj(s,t): 큐브 텍스쳐에서 샘플러 s를 이용해 샘플링을 한다. 이때 t.w 값에 의해 texture 좌표값 각각이 나뉘게(/) 된다.
transpose(x): x의 행과 열이 바뀐 전치행렬을 구한다.
trunc(x): x의 소숫점 아래 값을 버린 정수값을 얻는다.
[출처] 14. [Shader Study, HLSL 기본문법] Intrinsic Functions 내장함수 - 3 (토크게임엔진 개발자 모임) |작성자 Dark Wolf
S : 채도(saturation)를 뜻하는데, 어떤 특정 색상의 색의 양으로 보통 0~100%의 백분율로 나타낸다. 채도가 높을수록 색은 강렬해진다.
B : 명도(brightness)를 뜻하는데, 어떤 색 중 백색의 양으로 0%이면 흑이고 100%이면 백이다.
RGB -> HSB
채도 변화에 따른 RGB값 구하기
x: 채도
m: R,G,B중 최대값
(R,G,B) = ((R,G,B) - m)*x + m
명도도 영향을 주고 싶으면 아래처럼하면 비슷하게 나온다
b : 명도
(R,G,B) = (((R,G,B) - m)*x + m)*b
YUV란?
휘도 신호(Y)
휘도 신호와 적색 성분의 차(U)
휘도 신호와 청색 성분의 차(V)
한마디로 Y는 명암정도 U, V는 색상정보이다. 만약 색상을 회색으로 바꾸고 싶다면 Y값을 구해서 R, G, B값에 넣으면 된다
RGB -> YUV
Y=0.3R+0.59G +0.11B
U=(B-Y)x0.493
V=(R-Y)x0.877
YUV -> RGB
R=Y+0.956U+0.621V
G=Y+0.272U+0.647V
B=Y+1.1061U+1.703V
MessageBox 일정 시간 후에 사라지게 하기
메시지 박스 출력후 일정 시간 후에 자동으로 사라지게 하는 기능이 필요하면 넣으면 되겠다
#pragma once
#include <windows.h>
#include <tchar.h>
//Functions & other definitions required-->
typedef int (__stdcall *MSGBOXAAPI)(IN HWND hWnd,
IN LPCSTR lpText, IN LPCSTR lpCaption,
IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
typedef int (__stdcall *MSGBOXWAPI)(IN HWND hWnd,
IN LPCWSTR lpText, IN LPCWSTR lpCaption,
IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
int MessageBoxTimeoutA(IN HWND hWnd, IN LPCSTR lpText,
IN LPCSTR lpCaption, IN UINT uType,
IN WORD wLanguageId, IN DWORD dwMilliseconds);
int MessageBoxTimeoutW(IN HWND hWnd, IN LPCWSTR lpText,
IN LPCWSTR lpCaption, IN UINT uType,
IN WORD wLanguageId, IN DWORD dwMilliseconds);
#ifdef UNICODE
#define MessageBoxTimeout MessageBoxTimeoutW
#else
#define MessageBoxTimeout MessageBoxTimeoutA
#endif
//#define MB_TIMEDOUT 32000
int MessageBoxTimeoutA(HWND hWnd, LPCSTR lpText,
LPCSTR lpCaption, UINT uType, WORD wLanguageId,
DWORD dwMilliseconds)
{
static MSGBOXAAPI MsgBoxTOA = NULL;
if (!MsgBoxTOA)
{
HMODULE hUser32 = GetModuleHandle(_T("user32.dll"));
if (hUser32)
{
MsgBoxTOA = (MSGBOXAAPI)GetProcAddress(hUser32,
"MessageBoxTimeoutA");
//fall through to 'if (MsgBoxTOA)...'
}
else
{
//stuff happened, add code to handle it here
//(possibly just call MessageBox())
return 0;
}
}
if (MsgBoxTOA)
{
return MsgBoxTOA(hWnd, lpText, lpCaption,
uType, wLanguageId, dwMilliseconds);
}
return 0;
}
int MessageBoxTimeoutW(HWND hWnd, LPCWSTR lpText,
LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds)
{
static MSGBOXWAPI MsgBoxTOW = NULL;
if (!MsgBoxTOW)
{
HMODULE hUser32 = GetModuleHandle(_T("user32.dll"));
if (hUser32)
{
MsgBoxTOW = (MSGBOXWAPI)GetProcAddress(hUser32,
"MessageBoxTimeoutW");
//fall through to 'if (MsgBoxTOW)...'
}
else
{
//stuff happened, add code to handle it here
//(possibly just call MessageBox())
return 0;
}
}
if (MsgBoxTOW)
{
return MsgBoxTOW(hWnd, lpText, lpCaption,
uType, wLanguageId, dwMilliseconds);
}
return 0;
}