http://files.cnblogs.com/ququer/TYPlayer.rar
1.关于窗体变色
这个很多人都喜欢把:
效果:
原理说白了,就是hdc 4个通道的处理:
#define PCL_R(p) (((RGBQUAD*)(p))->rgbRed)
#define PCL_G(p) (((RGBQUAD*)(p))->rgbGreen)
#define PCL_B(p) (((RGBQUAD*)(p))->rgbBlue)
#define PCL_A(p) (((RGBQUAD*)(p))->rgbReserved)template
inline const T& ttMax (const T& _X, const T& _Y) {return (_X < _Y ? _Y : _X);}
templateinline const T& ttMin (const T& _X, const T& _Y) {return (_Y < _X ? _Y : _X);}
templateinline void ttSwap (T& t1, T& t2) { const T tmp=t1 ; t1=t2 ; t2=tmp ;}
templateinline T ttSquare (const T& t) {return t*t ;}
templateinline T ttClamp (const T& t, const T& tLow, const T& tHigh) {return ttMax (tLow, ttMin (tHigh, t)) ;}
int ttClamp0255 (int n) { return ttClamp (n, 0, 0xFF); } //0-255BITMAPINFO bi = {0};
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bIsOk = GetDIBits(m_memGDC->m_hBkDc, m_memGDC->m_hBitmap, 0, 0, NULL, &bi, DIB_RGB_COLORS); assert(bIsOk==1);
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biPlanes = 1;
RGBQUAD *pBits = (RGBQUAD*)malloc(iWidth * iHeigh * (bi.bmiHeader.biBitCount/8) * sizeof(BYTE));
bIsOk = GetDIBits(m_memGDC->m_hBkDc, m_memGDC->m_hBitmap, 0, iHeigh, (LPVOID)pBits, &bi, DIB_RGB_COLORS);
assert(bIsOk==1);RGBQUAD clAve = GetBitRandAveRGB(pBits, iWidth * iHeigh, 25);//计算伪平均颜色
for(int i=0; i != iWidth * iHeigh ; ++i)
{
if(IsCHGColor)
{
PCL_R(&pBits[i]) = ttClamp0255(PCL_R(&pBits[i]) + m_ChR - PCL_R(&clAve));
PCL_G(&pBits[i]) = ttClamp0255(PCL_G(&pBits[i]) + m_ChG - PCL_G(&clAve));
PCL_B(&pBits[i]) = ttClamp0255(PCL_B(&pBits[i]) + m_ChB - PCL_B(&clAve));
}
if(PCL_R(&pBits[i])==0 && PCL_G(&pBits[i])==0 && PCL_B(&pBits[i])==0)//防止完全透明
{
PCL_R(&pBits[i]) = 1;
PCL_G(&pBits[i]) = 1;
PCL_B(&pBits[i]) = 1;
}
PCL_A(&pBits[i]) = m_ChA;
}
SetDIBits(m_memGDC->m_hBkDc, m_memGDC->m_hBitmap, 0, iHeigh, (LPVOID)pBits, &bi, DIB_RGB_COLORS);更换四个通道的颜色只用改m_ChR m_ChG m_ChB m_ChA
说白了就是网上有一大堆的什么jpg开源的图片处理技术偷点代码就做了。
下面我要问几个问题:请高手回答:
1.如何提高效率
2.谁能改进一下,谢谢,我的邮箱:[email protected]
2.关于png带透明通道的图片拉伸
如何把B拉伸成A,用StretchBlt吧 ,可以拉伸时带透明通道的处理
像这样:
int a = 7;
int b = 7;
//四角拷贝
StretchBlt(hdc, 0, 0, a, b, hBkDc, 0, 0, a, b, SRCCOPY);
StretchBlt(hdc, dwt-a, 0, a, b, hBkDc, swt-a, 0, a, b, SRCCOPY);
StretchBlt(hdc, 0, dht-b, a, b, hBkDc, 0, sht-b, a, b, SRCCOPY);
StretchBlt(hdc, dwt-a, dht-b, a, b, hBkDc, swt-a, sht-b, a, b, SRCCOPY);
//边界拉伸
int x=7;
int y=7;
StretchBlt(hdc, x, 0, dwt-2*x, y, hBkDc, x, 0, swt-2*x, y, SRCCOPY);
StretchBlt(hdc, x, dht-y, dwt-2*x, y, hBkDc, x, sht-y, swt-2*x, y, SRCCOPY);StretchBlt(hdc, dwt-x, y, x, dht-2*y, hBkDc, swt-x, y, x, sht-2*y, SRCCOPY);
StretchBlt(hdc, 0, y, x, dht-2*y, hBkDc, 0, y, x, sht-2*y, SRCCOPY);
//拉伸中间区域
StretchBlt(hdc, x, y, dwt-2*x, dht-2*y, hBkDc, x, y, swt-2*x, sht-2*y, SRCCOPY);在用StretchBlt前 还可以设置拉伸属性哦:SetStretchBltMode(hDc, HALFTONE);(这个函数是可以秒杀几个gdi+的函数的)
3.关于窗体动画的看法
如果您的架构支持timer,如果您的窗体支持透明度更改,您就可以实现几乎70%任何动画了
如果您用到了D3D,几乎可以秒杀所有您看到的动画了。
如果您用到了webkit+D3D,您就可以用D3D渲染flash,请您把您的源代码发给我,邮箱[email protected]。
4.边框绘制
下面的代码暂时不用了(其实还是很有用处的) 存着自己看
其实最好的画边框的方法是 贴png框(带阴影),上面代码已经透露了 不懂可以问我QQ:820156394
colorAve = GetHdcRandAveRGB(m_memGDC->m_hBkDc, m_memGDC->m_iWidth, m_memGDC->m_iHeight, 25);
Graphics graph(m_memGDC->m_hBkDc);
RGBQUAD cl;
PCL_R(&cl) = GetRValue(colorAve);
PCL_G(&cl) = GetGValue(colorAve);
PCL_B(&cl) = GetBValue(colorAve);
PCL_A(&cl) = m_ChA;
DrawRoundRectange(&graph, cl, 1, 1, iWidth-4, iHeigh-4, 8);//内框
double k = 0.66;
PCL_R(&cl) = ttClamp0255(PCL_R(&cl)*k);
PCL_G(&cl) = ttClamp0255(PCL_G(&cl)*k);
PCL_B(&cl) = ttClamp0255(PCL_B(&cl)*k);
PCL_A(&cl) = m_ChA;
DrawRoundRectange(&graph, cl, 0, 0, iWidth-2, iHeigh-2, 8);//外框// gdi+画一个圆角的矩形
void DrawRoundRectange(Graphics *graph, RGBQUAD cl, int x, int y, int width, int height, int r)
{
graph->SetSmoothingMode(SmoothingModeHighQuality );
Pen pen(Color(PCL_A(&cl), PCL_R(&cl),PCL_G(&cl),PCL_B(&cl)));
int r2=r*2;
graph->DrawLine(&pen, x+r, y, x+width-r, y);graph->DrawLine(&pen, x+r, y+height,x+width-r, y+height);
graph->DrawLine(&pen, x, y+r, x, y+height-r);
graph->DrawLine(&pen, x+width, y+r, x+width, y+height-r);
graph->DrawArc(&pen, x, y, r2,r2,180,90);
graph->DrawArc(&pen, x+width-r2,y+height-r2,r2,r2,360,90);
graph->DrawArc(&pen, x+width-r2,y, r2,r2,270,90);
graph->DrawArc(&pen, x, y+height-r2,r2,r2,90,90);
}// gdi画一个圆角的矩形
void DrawRoundRectange(HDC hdc, COLORREF cl, int x, int y, int iWidth, int iHeigh, int r)
{
RECT rcRect = {x, y, iWidth, iHeigh};
HBRUSH brush = CreateSolidBrush(cl);
FrameRect(hdc, &rcRect, brush);
HPEN pen = CreatePen(PS_SOLID, 1, cl);
HPEN oldpen = (HPEN)SelectObject(hdc, pen);
int r2 = r*2;
Arc(hdc, x, y, x+r2, y+r2, x+r, y, x, y+r);
Arc(hdc, x+iWidth-r2, y, x+iWidth, y+r2, x+iWidth, y+r, x+iWidth-r, y);
Arc(hdc, x, y+iHeigh-r2, x+r2, y+iHeigh, x, y+iHeigh-r, x+r, y+iHeigh);
Arc(hdc, x+iWidth-r2, y+iHeigh-r2, x+iWidth, y+iHeigh, x+iWidth-r, y+iHeigh, x+iWidth, y+iHeigh-r);
SelectObject(hdc, oldpen);
}
5.关于gdi和gdi+混合渲染的原则:
一般出现的问题是很诡异的,代码没有错误,但就是画出来的东西及其诡异,你最需要注意,混合渲染的时候gdi+对象必须画完就释放就好了,换句话说,不能gdi+对象没有释放就用gdi函数乱画一同,
所以可以这样
{gdi+对象绘制
}
6.关于消息分发:
从主窗口分发消息,用一个对象管理器管理所有控件,控件和对象管理器均无句柄,
窗口对话框用类的子类化处理
对象分发消息主要按 控件的可见和disable属性 是否捕获鼠标 是否有焦点 以及控件状态
所有控件继承于CDUIWnd,用多态实现公用方法
每个控件都可以有n种渲染方式,这个在控件类中实现
对象管理器可维护一个timer列表。
对象管理器可维护一个对象列表。
7.关于未来的设想:
想添加 IE组件管理 用微软js引擎控制界面逻辑,还不是很了解
xml界面设计,这个还好
毛玻璃效果,不知道原理
edit控件,现在还嫌它太麻烦,没敢动它