好东西大家分享,不规则窗体,不规则按钮等
来源:http://forum.vclxx.org/topic.asp?TOPIC_ID=12875&FORUM_ID=12&CAT_ID=3&Topic_Title=ActiveSkin%2C%A7%EF%C5%DCForm%A5%7E%AB%AC%2C+%BA%7D%ABG%A4%B6%AD%B1%2E%2E%2E%A7%B9%BE%E3%B8%D1%B5%AA%7E&Forum_Title=C%2B%2B
Posted - 01/11/2002 : 10:34:22
--------------------------------------------------------------------------------
這篇是小弟在2000/7/2發表的文章, 再貼一次給大家參考..
ActiveSkin是個好東西, 但妳也可以自己做
妳也可以自己做到改變Form的外型...
連續這麼多封信在問這個問題, 一次給你全部的答案吧...
1.圓形(或橢圓)
HRGN rgn;
rgn = CreateEllipticRgn(50,100,400,300);
SetWindowRgn(this->Handle,rgn,true);
2.多邊形 (自訂座標位置, 此例為一個五芒星圖案)
HRGN rgn;
INT num[1];
TPoint points[10];
TRect wrect;
num[0]=10;
points[0].x = 304;
points[0].y = 24;
points[1].x = 232;
points[1].y = 160;
points[2].x = 64;
points[2].y = 160;
points[3].x = 192;
points[3].y = 264;
points[4].x = 136;
points[4].y = 392;
points[5].x = 304;
points[5].y = 336;
points[6].x = 456;
points[6].y = 392;
points[7].x = 424;
points[7].y = 264;
points[8].x = 552;
points[8].y = 160;
points[9].x = 384;
points[9].y = 160;
rgn = CreatePolyPolygonRgn( points, num, 1, WINDING );
SetWindowRgn(this->Handle, rgn, true);
3.文字外型 (你會直接看到一個FORM的外型變成 "C++Builder" , 很神奇喔! )
HRGN rgn;
BeginPath( Form1->Canvas->Handle );
SetBkMode( Form1->Canvas->Handle, TRANSPARENT );
Form1->Canvas->Font->Name = "Arial";this->Color = clBlue;
Form1->Canvas->Font->Size=100;Form1->Canvas->TextOut( 0, 0, "C++Builder");
EndPath( Form1->Canvas->Handle );
rgn = PathToRegion( Form1->Canvas->Handle );
SetWindowRgn(this->Handle, rgn, true);
4. 圖形外觀
這部分比較難, 你必須有修過"影像處理"或"電腦繪圖"等相關課程, 了解邊緣搜尋相關
演算法...
這裡我直接公佈原始碼, 供大家使用, 免除大家到處找元件, 有時還找到的只是試用版
,...#@#$ , 把source公開出來又何仿 ^_^ . . . .
(請搭配此演算法, 與 SetWindowRgn 函數)
HRGN __stdcall GetPictureRegion( HBITMAP hBmp, COLORREF cTransparentColor,
COLORREF cTolerance )
/**第一個參數: bmp 的 handle 第二個參數: 背景色 第三個參數: 容錯度 **/
{
HRGN hRgn = NULL;
if (hBmp)
{
HDC hMemDC = CreateCompatibleDC(NULL);
if (hMemDC)
{
BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm);
BITMAPINFOHEADER RGB32BITSBITMAPINFO = {
sizeof(BITMAPINFOHEADER),
bm.bmWidth,
bm.bmHeight,
1,
32,
BI_RGB,
0,
0,
0,
0,
0
};
VOID * pbits32;
HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO
*)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0);
if (hbm32)
{
HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);
HDC hDC = CreateCompatibleDC(hMemDC);
if (hDC)
{
BITMAP bm32;
GetObject(hbm32, sizeof(bm32), &bm32);
while (bm32.bmWidthBytes % 4)
bm32.bmWidthBytes++;
HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0,
SRCCOPY);
#define ALLOC_UNIT 100
DWORD maxRects = ALLOC_UNIT;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) +
(sizeof(RECT) * maxRects));
RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
pData->rdh.dwSize = sizeof(RGNDATAHEADER);
pData->rdh.iType = RDH_RECTANGLES;
pData->rdh.nCount = pData->rdh.nRgnSize = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
BYTE lr = GetRValue(cTransparentColor);
BYTE lg = GetGValue(cTransparentColor);
BYTE lb = GetBValue(cTransparentColor);
BYTE hr = (BYTE)min(0xff, lr + GetRValue(cTolerance));
BYTE hg = (BYTE)min(0xff, lg + GetGValue(cTolerance));
BYTE hb = (BYTE)min(0xff, lb + GetBValue(cTolerance));
BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) *
bm32.bmWidthBytes;
for (int y = 0; y < bm.bmHeight; y++)
{
for (int x = 0; x < bm.bmWidth; x++)
{
int x0 = x;
LONG *p = (LONG *)p32 + x;
while (x < bm.bmWidth)
{
BYTE b = GetRValue(*p);
if (b >= lr && b <= hr)
{
b = GetGValue(*p);
if (b >= lg && b <= hg)
{
b = GetBValue(*p);
if (b >= lb && b <= hb)
break;
}
}
p++;
x++;
}
if (x > x0)
{
if (pData->rdh.nCount >= maxRects)
{
GlobalUnlock(hData);
maxRects += ALLOC_UNIT;
hData = GlobalReAlloc(hData,
sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
pData = (RGNDATA *)GlobalLock(hData);
}
RECT *pr = (RECT *)&pData->Buffer;
SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
if (x0 < pData->rdh.rcBound.left)
pData->rdh.rcBound.left = x0;
if (y < pData->rdh.rcBound.top)
pData->rdh.rcBound.top = y;
if (x > pData->rdh.rcBound.right)
pData->rdh.rcBound.right = x;
if (y+1 > pData->rdh.rcBound.bottom)
pData->rdh.rcBound.bottom = y+1;
pData->rdh.nCount++;
if (pData->rdh.nCount == 2000)
{
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) +
(sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
p32 -= bm32.bmWidthBytes;
}
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) *
maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
SelectObject(hDC, holdBmp);
DeleteDC(hDC);
}
DeleteObject(SelectObject(hMemDC, holdBmp));
}
DeleteDC(hMemDC);
}
}
return hRgn;
}
註: 當一個表單失去 caption bar時, 你便無法用滑鼠拖曳此表單, 請將下面程式加
入 FormMouseDown 事件裡:
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
if( Button == mbLeft )
{
ReleaseCapture();
Perform( WM_SYSCOMMAND, 0xf012, 0 );
Application->ProcessMessages();
}
}
--
Chang-Kai Hsu
Department of Information and Computer Engineering Chung Yuan Christian University, Chung Li, Taiwan, 320, R.O.C.
Tel: 886-3-4563171 ext. 4725 ken@mcsl.ice.cycu.edu.tw
※ 引述《xingxilong》於 01/11/2002 12:14:20 發表之銘言:
>真的是太棒了。
keenn兄好樣,不藏私!
補充"圖形外觀"在Delphi 6中的作法:
1. 在Form上面放置一個Image
2. 為Image載入圖片(假設底色為白色)
3. 把Form和Image的AutoSize屬性皆設為True
4. 將Form的Transparent屬性設為True
5. 設定Form的TransparentColor屬性為圖片的底色(本例中設為白色)
6. 差點忘了,將Form的BorderStyle設為bsNone
7. 呈6, 記得為程式寫個可以關閉的方法