線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3859
推到 Plurk!
推到 Facebook!

關於不規則FORM的拖卸移動

答題得分者是:harpist
willycheng
一般會員


發表:7
回覆:7
積分:2
註冊:2006-12-02

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-07-04 20:33:55 IP:140.111.xxx.xxx 訂閱
暑假閒來無事想說來試試不規則的FORM 經過一翻搜尋找到了一些前輩們的文章 如: http://delphi.ktop.com.tw/board.php?cid=168&fid=913&tid=27860 http://delphi.ktop.com.tw/board.php?cid=168&fid=913&tid=28040 不過對於不規則FORM的移動卻無法成功以下是在BCB6下的程式碼 (不規則化的FORM是成功了~卻無法移動) 可能是在FormMouseDown裡的問題,不過我才算初學所以索性把程式碼都放上來不知道其他地方是否有錯... <textarea class="cpp" rows="10" cols="60" name="code">//--------------------------------------------------------------------------- #include using namespace std; #include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; HRGN __stdcall GetPictureRegion( HBITMAP, COLORREF, COLORREF); //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Image1->Picture->LoadFromFile("test.bmp"); Image1->AutoSize = true; Image1->Transparent = true; Form1->AutoSize = true; Form1->BorderStyle = bsNone; HBITMAP h = Image1->Picture->Bitmap->Handle; HRGN hrgn = GetPictureRegion(h,0x0,0x0); //呼叫描邊函數(設圖片背景為黑色) //若圖片背景為白色將上一行改成 HRGN hrgn = GetPictureRegion(h,0x00ffffff,0x0); SetWindowRgn(Handle,hrgn,true); } //--------------------------------------------------------------------------- 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; } void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if( Button == 0 ) { ReleaseCapture(); Perform( WM_SYSCOMMAND, 0xf012, 0 ); Application->ProcessMessages(); } } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- </textarea>
編輯記錄
willycheng 重新編輯於 2007-07-04 20:34:57, 註解 無‧
harpist
資深會員


發表:3
回覆:251
積分:430
註冊:2002-10-03

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-07-05 02:17:44 IP:59.104.xxx.xxx 未訂閱
<textarea class="cpp" rows="10" cols="60" name="code"> //--------------------------------------------------------------------------- void __fastcall TForm1::Image1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if( Button == 0 ) { ReleaseCapture(); Perform( WM_SYSCOMMAND, 0xf012, 0 ); Application->ProcessMessages(); } } //--------------------------------------------------------------------------- </textarea>
------
~§~迷時師渡,悟了自渡~§~
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-07-30 15:14:36 IP:210.64.xxx.xxx 訂閱
最近引用了GetPictureRegion這個函式,發現原作者的程式有點小觀念上的誤會,於是修正如下:
主要的修改僅有最上面的地方! 改成這樣後,就可以"正常"的呼叫它了,比如說

HRGN hrgn = GetPictureRegion(h,clRed,0);

HRGN hrgn = GetPictureRegion(h,RGB(0,255,128),0);

這規化COLORREF 的值正確是 0x00bbggrr ,也符合TColor型別

希望今後看到這篇的人可以散播正確的寫法~ ^_^

[code cpp]
HRGN __stdcall TForm1::GetPictureRegion( HBITMAP hBmp, COLORREF cTransparentColor,COLORREF cTolerance )
/**第一個參數: bmp 的 handle 第二個參數: 背景色 第三個參數: 容錯度 **/
{
{ //modify by 蕭沖 20090730
//原作者在比對像素時勿把記憶體位址(低至高)內容當成RGB,事實上應該是,BGR
int r = GetRValue(cTransparentColor);
int g = GetGValue(cTransparentColor);
int b = GetBValue(cTransparentColor);
cTransparentColor = RGB(b,g,r); //將錯就錯,修正這裡!
} // end by 蕭沖

using namespace std;
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;
}

[/code]
------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
系統時間:2024-11-22 8:38:22
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!