http://www.91code.net/source/adv_ui/skins/skins.zip
解决方案 »
- 请教,多线程中设置listview单元格数据出错
- from 子句语法错误,在线等......
- 大虾,怎样生成汇编代码?以及怎样编译汇编代码?
- 看看这个东东。很有趣呀
- sock的小Case!!请指点
- 用ADO连接SQL SERVER。调用存储过程,如果存储过程结果无记录、为 return -1000 。ADO如何得到此结果-1000。
- 怎樣可以刪除一個文件?
- MSDN出错,请帮助 cann't open mdsn020.col
- 谁有自画窗体的原码(主要是自画最大,最小,关闭窗口按钮),能给我看看吗?
- 异想天开的问题???,进来就给分!!!!
- vc++高手请进!
- TRACE宏的问题?---请各位指教
这个也不错。
很优秀的工具!
规则窗口的过程是:首先定义一个CRgn类,并用各种初始化函数创建CRgn类的具体区
域,然后调用CWnd::SetWindowRgn()函数创建不规则窗口。
CRgn是从CgdiObject衍生出来的类,用来确定一个多边形、椭圆或者由多边形及椭
圆合成的范围,在程序中主要会用到CreateRectRgnIndirect()、
CreateEllipticRgnIndirect()、CreatePolygonRgn()三个函数。
CreateRectRgnIndirect(LPCRECT
lpRect)函数创建一个矩形区域,参数lpRect指定所创建的矩形区域在窗口用户区中的
left(左)、top(上)、right(右)、bottom(下)坐标。例如:
CRgn MyRgn;
RECT m_rect;
m_rect.left=0; m_rect.top=0; m_rect.right=500; m_rect.bottom=300;
MyRgn.CreateRectRgnIndirect( &m_rect );
CreateEllipticRgnIndirect(LPCRECT
lpRect)函数创建一个椭圆形区域,参数lpRect指定所创建的椭圆形区域在窗口用户区
中的left(左)、top(上)、right(右)、bottom(下)坐标,如果指定right坐标
与left坐标之差等于bottom坐标与top坐标之差,则创建的区域是一个圆。例如:
CRgn MyRgn;
RECT m_rect;
m_rect.left=0; m_rect.top=0; m_rect.right=500; m_rect.bottom=300;
MyRgn.CreateEllitpticRgnIndirect( &m_rect );
CreatePolygonRgn(LPPOINT lpPoints, int nCount, int
nMode)函数创建一个多边形区域,参数lpPoints指向一个POINT结构数组,在POINT结构
数组中每个POINT结构项,用来确定多边形顶点在窗口用户区中的坐标;nCount说明
POINT结构数组中POINT结构项的数目,也就是多边形的顶点数;nMode指定多边形的填
充方式,一般使用ALTERNATE方式。例如创建一个三角形:
CRgn MyRgn;
POINT Points[3];
Points[0].x=Points[0].y=0; Points[1].x=10; Points[1].y=30; Points[2].x=5;
Points[2].y=60;
MyRgn.CreatePolygonRgn(Points, 3, ALTERNATE);
利用以上的函数创建区域后,就可以调用CWnd::SetWindowRgn(HRGN hRgn, BOOL
bRedraw)来创建非矩形的窗口了。SetWindowRgn()函数参数说明:hRgn是一个CRgn类的
句柄;bRedraw如果被设置成TRUE,那么,在窗口次序发生变化时,系统会发送
WM_WINDOWPOSCHANGING和WM_WINDOWPOSCHANGED消息给窗口。
如果要创建外形更复杂的窗口,例如mp3播放器Soniq的一个播放界面,就是两个圆
形部分重合形成的。对于这类窗口的创建,还要用到CRgn类另外一个极其重要的函
数——CombineRgn()。首先要说明的是:在VC++5的在线帮助中,将这个函数归入了初
始化(Initialization)类型中,实际上,如果定义的CRgn类在没有使用其它初始化函
数初始化之前,就调用这个函数的话,程序将会失败,所以,这个函数似乎应该归入
operation类更恰当。
CombineRgn(CRgn* pRgn1, CRgn* pRgn2, int
nCombineMode)函数用来创建一个由多个多边形、椭圆合成的不规则区域。pRgn1、
pRgn2分别指向参与合成不规则区域的多边形或椭圆形;nCombineMode说明合成的方式
:RGN_AND最后的区域是pRgn1和pRgn2的重叠部分;RGN_DIFF最后的区域是pRgn1中不包
含pRgn2的部分;RGN_OR最后的区域同时包含pRgn1和pRgn2;RGN_XOR最后的区域同时包
含pRgn1和pRgn2,但不包含pRng1和pRng2重叠的部分。例如,创建一个类似Soniq播放
器的界面:
......
RECT m_Cyc1;
RECT m_Cyc2;
CRgn RgnCyc1;
CRgn RgnCyc2;
CRgn RgnDlg;
m_Cyc1.left=100; m_Cyc1.top=5; m_Cyc1.right=200; m_Cyc1.bottom=105;
m_Cyc2.left=80; m_Cyc2.top=85; m_Cyc2.right=180; m_Cyc2.bottom=185;
RgnDlg.CreateEllipticRgnIndirect( &m_Cyc1 );
RgnCyc1.CreateEllipticRgnIndirect( &m_Cyc1 );
RgnCyc2.CreateEllipticRgnIndirect( &m_Cyc2 );
RgnDlg.CombineRgn( &RgnCyc1, &RgnCyc2, RGN_OR );
MyWin.SetWindowRgn( (HRGN)RgnDlg, TURE );
......
以上就是利用VC实现不规则窗口的方法
{
// Construction
public:
CBearDlg(CWnd* pParent = NULL); // standard constructorpublic:
void DrawBear(CString &strfile);
// Dialog Data
//{{AFX_DATA(CBearDlg)
enum { IDD = IDD_DIALOG1 };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
public:
HBITMAP hBmp;
HBITMAP hPrevBmp;
HDC hMemDC;
HRGN hRegion;
BITMAP bmInfo;
LPCREATESTRUCT m_lpCreateStruct;
int m_iAniSeq;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CBearDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL// Implementation
protected: // Generated message map functions
//{{AFX_MSG(CBearDlg)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg BOOL OnEraseBkgnd(CDC *pDC);
afx_msg void OnDestroy();
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg UINT OnNcHitTest(CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
m_lpCreateStruct = lpCreateStruct;
// TODO: Add your specialized creation code here
CString file = "BEER1.Bmp";
DrawBear(file);
SetTimer(0,500,NULL);
return 0;
}void CBearDlg::OnDestroy()
{
CDialog::OnDestroy();
KillTimer(0);
// TODO: Add your message handler code here
SelectObject(hMemDC,hPrevBmp);
if(hBmp)
DeleteObject(hBmp);
}
BOOL CBearDlg::OnEraseBkgnd(CDC *pDC)
{
BitBlt(pDC->m_hDC,0,0,bmInfo.bmWidth,bmInfo.bmHeight,
hMemDC,0,0,SRCCOPY);
return FALSE;
}void CBearDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
char szBmp[20];
if(m_iAniSeq == 9)
m_iAniSeq = 1;
sprintf(szBmp,"BEER%d.bmp",m_iAniSeq);
CString file = szBmp;
DrawBear(file);
m_iAniSeq ++;
CDialog::OnTimer(nIDEvent);
}
void CBearDlg::DrawBear(CString &strfile)
{
//if(hBmp)DeleteObject(hBmp);
CString filename = strfile;
hBmp = (HBITMAP)LoadImage(m_lpCreateStruct->hInstance,filename,IMAGE_BITMAP,
0,0,LR_LOADFROMFILE);
hRegion = BitmapRegion(hBmp,RGB(0,0,0));
if(hRegion)
SetWindowRgn(hRegion,TRUE);
GetObject(hBmp,sizeof(bmInfo),&bmInfo);
hMemDC = CreateCompatibleDC(NULL);
hPrevBmp = (HBITMAP)SelectObject(hMemDC,hBmp);
//SelectObject(hMemDC,hPrevBmp);
if(hBmp)
DeleteObject(hBmp);
}
{
// We create an empty region
HRGN hRegion=NULL;
// If the passed bitmap is NULL, go away!
if(!hBitmap)
return hRegion;
// We create a memory context for working with the bitmap
// The memory context is compatible with the display context (screen)
HDC hMemDC=CreateCompatibleDC(NULL);
// If no context is created, go away, too!
if(!hMemDC)
return hRegion;
// Computation of the bitmap size
BITMAP bmBitmap;
GetObject(hBitmap, sizeof(bmBitmap), &bmBitmap);
// In order to make the space for the region, we
// create a bitmap with 32bit depth color and with the
// size of the loaded bitmap!
BITMAPINFOHEADER RGB32BITSBITMAPINFO=
{
sizeof(BITMAPINFOHEADER),
bmBitmap.bmWidth,
bmBitmap.bmHeight,
1,32,BI_RGB,0,0,0,0,0
};
// Here is the pointer to the bitmap data
VOID *pBits;
// With the previous information, we create the new bitmap!
HBITMAP hNewBitmap;
hNewBitmap=CreateDIBSection(hMemDC,
(BITMAPINFO *)&RGB32BITSBITMAPINFO,
DIB_RGB_COLORS,&pBits,NULL,0); // If the creation process succeded...
if(hNewBitmap)
{
// We select the bitmap onto the created memory context
// and then we store the previosly selected bitmap on this context!
HBITMAP hPrevBmp=(HBITMAP) SelectObject(hMemDC,hNewBitmap);
// We create another device context compatible with the first!
HDC hDC=CreateCompatibleDC(hMemDC);
// If success...
if(hDC)
{
// We compute the number of bytes per row that the bitmap contains, rounding to 32 bit-multiples
BITMAP bmNewBitmap;
GetObject(hNewBitmap,sizeof(bmNewBitmap),&bmNewBitmap);
while(bmNewBitmap.bmWidthBytes % 4)
bmNewBitmap.bmWidthBytes++;
// Copy of the original bitmap on the memory context!
HBITMAP hPrevBmpOrg=(HBITMAP) SelectObject(hDC,hBitmap);
BitBlt(hMemDC,0,0,bmBitmap.bmWidth,bmBitmap.bmHeight,hDC,0,0,SRCCOPY); // In order to optimize the code, we don't call the GDI each time we
// find a transparent pixel. We use a RGN_DATA structure were we store
// consecutive rectangles, until we have a large amount of them and then we crete
// the composed region with ExtCreateRgn(), combining it with the main region.
// Then we begin again initializing the RGN_DATA structure and doing another
// iteration, until the entire bitmap is analyzed. // Also, in order to not saturate the Windows API with calls for reserving
// memory, we wait until NUMRECT rectangles are stores in order to claim
// for another NUMRECT memory space!
#define NUMRECT 100
DWORD maxRect = NUMRECT;
// We create the memory data
HANDLE hData=GlobalAlloc(GMEM_MOVEABLE,sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRect));
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);
// We study each pixel on the bitmap...
BYTE *Pixeles=(BYTE*) bmNewBitmap.bmBits+(bmNewBitmap.bmHeight-1)*bmNewBitmap.bmWidthBytes;
// Main loop
for(int Row=0;Row<bmBitmap.bmHeight;Row++)
{
// Horizontal loop
for(int Column=0;Column<bmBitmap.bmWidth;Column++)
{
// We optimized searching for adyacent transparent pixels!
int Xo=Column;
LONG *Pixel=(LONG*) Pixeles+Column; while(Column<bmBitmap.bmWidth)
{
BOOL bInRange=FALSE; // If the color is that indicated as transparent...
if( GetRValue(*Pixel)==GetRValue(cTransparentColor) &&
GetGValue(*Pixel)==GetGValue(cTransparentColor) &&
GetBValue(*Pixel)==GetBValue(cTransparentColor) )
bInRange=TRUE; if((bIsTransparent) && (bInRange))
break; if((!bIsTransparent) && (!bInRange))
break; Pixel++;
Column++;
} // while (Column < bm.bmWidth)
if(Column>Xo)
{
// We add the rectangle (Xo,Row),(Column,Row+1) to the region // If the number of rectangles is greater then NUMRECT, we claim
// another pack of NUMRECT memory places!
if (pData->rdh.nCount>=maxRect)
{
GlobalUnlock(hData);
maxRect+=NUMRECT;
hData=GlobalReAlloc(hData,sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRect),GMEM_MOVEABLE);
pData=(RGNDATA *)GlobalLock(hData);
}
RECT *pRect=(RECT*) &pData->Buffer;
SetRect(&pRect[pData->rdh.nCount],Xo,Row,Column,Row+1);
if(Xo<pData->rdh.rcBound.left)
pData->rdh.rcBound.left=Xo; if(Row<pData->rdh.rcBound.top)
pData->rdh.rcBound.top=Row; if(Column>pData->rdh.rcBound.right)
pData->rdh.rcBound.right=Column;
if(Row+1>pData->rdh.rcBound.bottom)
pData->rdh.rcBound.bottom=Row+1;
pData->rdh.nCount++; // In Win95/08 there is a limitation on the maximum number of
// rectangles a RGN_DATA can store (aprox. 4500), so we call
// the API for a creation and combination with the main region
// each 2000 rectangles. This is a good optimization, because
// instead of calling the routines for combining for each new
// rectangle found, we call them every 2000 rectangles!!!
if(pData->rdh.nCount==2000)
{
HRGN hNewRegion=ExtCreateRegion(NULL,sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRect),pData);
if (hNewRegion) {
// Si ya existe la región principal,sumamos la nueva,
// si no,entonces de momento la principal coincide con
// la nueva región.
if (hRegion) {
CombineRgn(hRegion,hRegion,hNewRegion,RGN_OR);
DeleteObject(hNewRegion);
} else
hRegion=hNewRegion;
}
// Volvemos a comenzar la suma de rectángulos
pData->rdh.nCount=0;
SetRect(&pData->rdh.rcBound,MAXLONG,MAXLONG,0,0);
}
} // if (Column > Xo)
} // for (int Column ...) // Nueva Row. Lo del negativo se debe a que el bitmap está invertido
// verticalmente.
Pixeles -= bmNewBitmap.bmWidthBytes;
} // for (int Row...) // Una vez finalizado el proceso,procedemos a la fusión de la
// región remanente desde la última fusión hasta el final
HRGN hNewRegion=ExtCreateRegion(NULL,sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRect),pData); if(hNewRegion)
{
// If the main region does already exist, we add the new one,
if(hRegion)
{
CombineRgn(hRegion,hRegion,hNewRegion,RGN_OR);
DeleteObject(hNewRegion);
}
else
// if not, we consider the new one to be the main region at first!
hRegion=hNewRegion;
}
// We free the allocated memory and the rest of used ressources
GlobalFree(hData);
SelectObject(hDC,hPrevBmpOrg);
DeleteDC(hDC);
}// if (hDC) SelectObject(hMemDC,hPrevBmp);
DeleteDC(hMemDC);
} //if (hNewBitmap) return hRegion;
}
[email protected]
我没话说了。
收到乐吗?
[email protected]
等你回复,我要结帖了!