|
Transparent는 화면에 있는 정보의 컬러를 그대로 가지고 와서 찍어주는 그런 기능입니다.
모든 객체는 사각형인데, 그 뒤의 컬러의 정보를 가지고 와서 내 객체에 뿌려줌으로써
투명하게 보이는 것처럼 처리를 하는 것입니다.
그렇기 때문에 배경과 라벨에 해당하는 처리를 다시 하지 않으시면 글자가 겹쳐져서
보이는 것은 어쩌면 당연한 일인지도 모릅니다.
Repaint() 메소드와 OnPaint 이벤트를 적당히 섞어서 잘 조합하신다면 원하시는 결과를
얻으실 수 있을것 같습니다.
그리고, Windows API에서 투명으로 찍는 API에 버그가 발견되어 MS에서 다시 코드를 올려
놓은 적이 있었습니다. 아래는 그것을 빌더로 파싱한 코드입니다.
/**********************************************************************/
// DrawTransparentBitmap
// MSDN용 버그 패치 Transparent Bitmap Drawing 루틴, 하지만 느리다
/**********************************************************************/
void __fastcall DrawTransparentBitmap(TCanvas *canvas, Graphics::TBitmap *bmp, int xStart, int yStart, int cTransparentColor)
{
Windows::TBitmap bm;
TColorRef cColor;
HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave, oldBmp, bmBackOld, bmObjectOld, bmMemOld, bmSaveOld, hBmp;
HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave, dc;
TPoint ptSize;
Main->BITMAP_BUFFER->Assign(bmp);
try {
dc = canvas->Handle;
hBmp = Main->BITMAP_BUFFER->Handle;
hdcTemp = CreateCompatibleDC(dc);
oldBmp = SelectObject(hdcTemp, hBmp);
GetObject(hBmp, sizeof(bm), &bm);
ptSize.x = bm.bmWidth;
ptSize.y = bm.bmHeight;
hdcBack = CreateCompatibleDC(dc);
hdcObject = CreateCompatibleDC(dc);
hdcMem = CreateCompatibleDC(dc);
hdcSave = CreateCompatibleDC(dc);
bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
bmAndMem = CreateCompatibleBitmap(dc, ptSize.x, ptSize.y);
bmSave = CreateCompatibleBitmap(dc, ptSize.x, ptSize.y);
bmBackOld = SelectObject(hdcBack, bmAndBack);
bmObjectOld = SelectObject(hdcObject, bmAndObject);
bmMemOld = SelectObject(hdcMem, bmAndMem);
bmSaveOld = SelectObject(hdcSave, bmSave);
SetMapMode(hdcTemp, GetMapMode(dc));
BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
cColor = SetBkColor(hdcTemp, cTransparentColor);
BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
SetBkColor(hdcTemp, cColor);
BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY);
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, dc, xStart, yStart, SRCCOPY);
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
BitBlt(dc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY);
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
DeleteObject(SelectObject(hdcBack, bmBackOld));
DeleteObject(SelectObject(hdcObject, bmObjectOld));
DeleteObject(SelectObject(hdcMem, bmMemOld));
DeleteObject(SelectObject(hdcSave, bmSaveOld));
SelectObject(hdcTemp, oldBmp);
DeleteDC(hdcMem);
DeleteDC(hdcBack);
DeleteDC(hdcObject);
DeleteDC(hdcSave);
DeleteDC(hdcTemp);
} catch (...) {}
}
또, 아래는 좀 더 부드럽게 보여주기 위한 멀티미디어 타이머 처리입니다. 그런데,
개인적으로는 저 정도의 스크롤이라면 (사람이 눈으로 볼 수 있는 정도의 속도라면)
Timer도 충분하고, 움직이는 픽셀 정도만 작게 잡아주시면 될 것 같습니다.
MMRESULT TIMER;
int TIMER_INTERVAL, TIMER_RESOLUTION;
TIMER_INTERVAL = 100; /* 타이머 간격 */
TIMER_RESOLUTION = 1000; /* 타이머 정확도. 최대 오차 범위는 1000ms */
// 타이머 생성
TIMER = timeSetEvent(TIMER_INTERVAL, TIMER_RESOLUTION, TimerTick, (DWORD)this, TIME_PERIODIC);
// 함수..
extern "C" void CALLBACK TimerTick(UINT itTimerID, UINT uiMessage, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
// 쭈주죽 처리.....
}
cuperido
초록물고기 님이 쓰신 글 :
: 소스를 아래와 같이 수정했습니다.
: 그런데... image콤포넌의 속성을 transparent = true로 놓고 컴파일 하면...
: 라벨에서와 같이 글자가 겹쳐 버리는 현상이 일어남니다.
: 왜 그런지 .. 첨부된 소스를 참조하시고.. 조언좀.. 부탁 드림니다.
: 수고 하세요.
:
:
:
: 공부맨 님이 쓰신 글 :
: : 저같은 경운 Bitmap에 먼저 (이동하는 문자를)그린후에 폼위의 Image에 bitblt 하는 방법으로 했습니다. 물론 폼엔 Transparent = true; 로 했구요.
: : 동영상 플레이어나 tv카드 화면 상에서도 투명하게 잘 동작 하는군요.
: :
: : 그리고 '아주' 부드럽게...는 잘 모르겟습니다.
: : 멀티미디어타이머를 쓰든 쓰레드를 쓰든 아주 약간씩 틱틱거리는듯한 느낌을 없앨 수 없더군요.
: : direct draw 로 cpu 100% 다 할당해서 효과주면 그나마 좀 나아지긴 하던데;;;
: : 카운터 보드를 달아서 인터럽트를 이용하는 방법도 있다고는 합니다만...
: : 완벽하게 하려면 리얼타임 os가 필요할듯;;;
: :
: :
: : 초록물고기 님이 쓰신 글 :
: : : 안녕하세요.
: : : 화면으로 원하는 메시지를 흘러가듯이 표현하려고합니다.
: : : 마치 TV에서... 좌에서 우로 흐르는 메세지처럼...
: : : 그래서 일단 투명한 폼에... 라벨을 올려놓고... 글자를 한글자씩 찍었는데...
: : : Lable 의 속성이 Transparent가 false일때는 글자가 한글자씩 옆으로 찍히는 것이 보이는데..
: : : Label 의 속성이 Transparent가 true 일때는... 글자가 겹쳐져 버리는 현상이 나타납니다.
: : : label1->Caption = "" 로 초기화 시켜도 먹히지 않습니다.
: : :
: : : 간단히 첨부한 소스는 Lable 의 속성이 Transparent가 false 이어서... 한글자씩 찍히나...
: : : Transparent를 true로 놓고 컴파일 해보시면... 문자가 겹쳐지는 현상이 일어남니다.
: : :
: : : 무엇이 문제인지요? 해결방안이 있는지요.
: : : 일단 흘러가는 효과를 내기 위해 투명윈도우에 라벨을 놓고, 라벨까지 투명 속성을 주어
: : : 만들려 했는데...
: : : 문자가 흘러가는 효과를 아주 부드럽게 내기위한 다른 방법으로는 어떤것이 있을수 있는지요?
: : :
: : : 수고하세요.
|