第一次写随笔,我本来想将win32窗口的标题栏设置成渐变色,像这样的效果
但发现找不到设置标题栏属性的api,SetWindowLong也只是增减窗口的固定的样式而已。所以想到一个思路,把标题栏去掉,自己绘制一个标题栏,包括标题栏上的按钮都自己来绘制创建。这里用到了gdi+,对于这个库也是刚接触到的。
最后程序实现的效果如下。
代码:
1 #ifndef ULONG_PTR 2 #define ULONG_PTR unsigned long* 3 #endif 4 #include <windows.h> 5 //#include <objidl.h> 6 #include <gdiplus.h> 7 using namespace Gdiplus; 8 #pragma comment (lib,"Gdiplus.lib") 9 #define ID_BUTTON1 1 10 #define ID_BUTTON2 2 11 HINSTANCE hInst; 12 13 void LoadBkImge(HDC hdc) 14 { 15 Graphics graphics(hdc); 16 Image image(L"pic1.png"); 17 graphics.DrawImage(&image,0,25); 18 } 19 20 21 void FillRec(HDC hdc,Rect myRect,Color* colors,float *positions,int i) 22 { 23 Graphics graphics(hdc); 24 //多彩渐变色 25 LinearGradientBrush myLinearGradientBrush( 26 myRect, 27 Color(255,255,255,0), 28 Color(255,255,0,0), 29 LinearGradientModeVertical 30 );//LinearGradientModeHorizontal*/ 31 32 myLinearGradientBrush.SetInterpolationColors(colors, positions, i); 33 graphics.FillRectangle(&myLinearGradientBrush,myRect); 34 } 35 36 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 37 38 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow) 39 { 40 HWND hWnd; 41 MSG msg; 42 WNDCLASS wndClass; 43 GdiplusStartupInput gdiplusStartupInput; 44 ULONG_PTR gdiplusToken; 45 hInst=hInstance; 46 47 // Initialize GDI+. 48 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); 49 50 wndClass.style = CS_HREDRAW | CS_VREDRAW|DS_CENTER; 51 wndClass.lpfnWndProc = WndProc; 52 wndClass.cbClsExtra = 0; 53 wndClass.cbWndExtra = 0; 54 wndClass.hInstance = hInstance; 55 wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 56 wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); 57 wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 58 wndClass.lpszMenuName = NULL; 59 wndClass.lpszClassName = TEXT("Gdiplustest"); 60 61 RegisterClass(&wndClass); 62 63 hWnd = CreateWindow( 64 TEXT("Gdiplustest"), 65 TEXT("Gdiplustest"), 66 WS_OVERLAPPED|WS_POPUP, 67 CW_USEDEFAULT, 68 CW_USEDEFAULT, 69 400, 70 250, 71 NULL, 72 NULL, 73 hInstance, 74 NULL); 75 76 ShowWindow(hWnd, iCmdShow); 77 UpdateWindow(hWnd); 78 79 while(GetMessage(&msg, NULL, 0, 0)) 80 { 81 TranslateMessage(&msg); 82 DispatchMessage(&msg); 83 } 84 85 GdiplusShutdown(gdiplusToken); 86 return msg.wParam; 87 } 88 89 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 90 WPARAM wParam, LPARAM lParam) 91 { 92 static HDC hdc; 93 static HWND hButton1,hButton2; 94 PAINTSTRUCT ps; 95 LPDRAWITEMSTRUCT pdis; 96 97 switch(message) 98 { 99 case WM_CREATE: 100 { 101 //窗口居中显示 102 int scrWidth,scrHeight; 103 RECT rect; 104 scrWidth=GetSystemMetrics(SM_CXSCREEN); 105 scrHeight=GetSystemMetrics(SM_CYSCREEN); 106 GetWindowRect(hWnd,&rect); 107 rect.left=(scrWidth-rect.right)/2; 108 rect.top=(scrHeight-rect.bottom)/2; 109 SetWindowPos(hWnd,HWND_TOP,rect.left,rect.top,rect.right,rect.bottom,SWP_SHOWWINDOW); 110 hButton1=CreateWindow("button","",WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,355,5,15,15,hWnd,(HMENU)ID_BUTTON1,hInst,NULL); 111 hButton2=CreateWindow("button","",WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,380,5,15,15,hWnd,(HMENU)ID_BUTTON2,hInst,NULL); 112 113 // 114 hdc=GetDC(hWnd); 115 return 0; 116 } 117 case WM_SIZE: 118 return 0; 119 case WM_PAINT: 120 { 121 hdc = BeginPaint(hWnd, &ps); 122 LoadBkImge(hdc); 123 Rect myRect(0,0,400,25); 124 125 // 126 Color colors[]={ 127 Color(255,255,255), 128 Color(247,251,255), 129 Color(239,239,247), 130 Color(222,227,231), 131 Color(231,235,239), 132 Color(214,219,222) 133 }; 134 float positions[]={ 135 0.0f, 136 0.2f, 137 0.4f, 138 0.6f, 139 0.8f, 140 1.0f 141 }; 142 FillRec(hdc,myRect,colors,positions,6); 143 Graphics graphics(hdc); 144 Pen pen1(Color(255,255,255,255)); 145 Pen pen2(Color(255,160,160,160)); 146 Pen pen3(Color(255,181,178,181)); 147 graphics.DrawLine(&pen1,0,0,400,0); 148 graphics.DrawLine(&pen2,0,1,400,1); 149 graphics.DrawLine(&pen3,0,25,400,25); 150 151 EndPaint(hWnd, &ps); 152 return 0; 153 } 154 case WM_COMMAND: 155 { 156 switch(wParam) 157 { 158 case ID_BUTTON1: 159 { 160 ShowWindow(hWnd,SW_SHOWMINIMIZED); 161 break; 162 } 163 case ID_BUTTON2: 164 { 165 PostQuitMessage(0); 166 break; 167 } 168 // 169 } 170 171 return 0; 172 173 } 174 175 case WM_DRAWITEM: 176 { 177 178 pdis=(LPDRAWITEMSTRUCT)lParam; 179 //SetBkMode(pdis->hDC, TRANSPARENT ); 180 FillRect(pdis->hDC,&pdis->rcItem,NULL); 181 FrameRect(pdis->hDC,&pdis->rcItem,(HBRUSH)GetStockObject(BLACK_BRUSH)); 182 183 int cx=pdis->rcItem.right-pdis->rcItem.bottom; 184 int cy=pdis->rcItem.bottom-pdis->rcItem.top; 185 186 switch(pdis->CtlID) 187 { 188 189 case ID_BUTTON1: 190 { 191 Graphics graphics(pdis->hDC); 192 Rect rectt(0,0,40,30); 193 Color colors[]={ 194 Color(247,251,255), 195 Color(239,239,247), 196 Color(222,227,231), 197 Color(231,235,239), 198 }; 199 float positions[]={ 200 0.0f, 201 0.333333f, 202 0.666666f, 203 1.0f 204 }; 205 FillRec(pdis->hDC,rectt,colors,positions,4); 206 { 207 SolidBrush m_pBrush(Color(255,0,0,0)); 208 PointF point1(3.0f, 6.5f); 209 PointF point2(12.0f, 6.5f); 210 PointF point3(12.0f, 8.50f); 211 PointF point4(3.0f, 8.50f); 212 PointF points[4] = {point1, point2, point3,point4}; 213 graphics.FillPolygon(&m_pBrush, points, 4, FillModeAlternate); 214 } 215 216 break; 217 } 218 219 case ID_BUTTON2: 220 { 221 Graphics graphics(pdis->hDC); 222 Rect rectt(0,0,40,30); 223 Color colors[]={ 224 Color(247,251,255), 225 Color(239,239,247), 226 Color(222,227,231), 227 Color(231,235,239), 228 }; 229 float positions[]={ 230 0.0f, 231 0.33333f, 232 0.66633f, 233 1.0f 234 }; 235 FillRec(pdis->hDC,rectt,colors,positions,4); 236 237 SolidBrush m_pBrush(Color(255,0,0,0)); 238 // 239 PointF point1(2.0f, 4.0f); 240 PointF point2(4.0f, 2.0f); 241 PointF point3(13.0f, 11.0f); 242 PointF point4(11.0f, 13.0f); 243 PointF points[4] = {point1, point2, point3,point4}; 244 graphics.FillPolygon(&m_pBrush, points, 4, FillModeAlternate); 245 // 246 PointF point5(13.0f, 4.0f); 247 PointF point6(11.0f, 2.0f); 248 PointF point7(2.0f, 11.0f); 249 PointF point8(4.0f, 13.0f); 250 251 PointF points2[4] = {point5, point6, point7,point8 }; 252 graphics.FillPolygon(&m_pBrush, points2, 4, FillModeAlternate); 253 } 254 break; 255 } 256 //if (pdis->itemState & ODS_SELECTED) 257 // InvertRect (pdis->hDC, &pdis->rcItem) ; 258 259 // Draw a focus rectangle if the button has the focus 260 261 if (pdis->itemState & ODS_FOCUS) 262 { 263 pdis->rcItem.left += cx / 16 ; 264 pdis->rcItem.top += cy / 16 ; 265 pdis->rcItem.right -= cx / 16 ; 266 pdis->rcItem.bottom -= cy / 16 ; 267 268 DrawFocusRect (pdis->hDC, &pdis->rcItem) ; 269 } 270 return 0 ; 271 } 272 273 case WM_DESTROY: 274 PostQuitMessage(0); 275 return 0; 276 case WM_LBUTTONDOWN: 277 SendMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0); 278 return 0; 279 default: 280 return DefWindowProc(hWnd, message, wParam, lParam); 281 } 282 }
说明:
这里有一个严重的问题,如何设置按钮的背景透明?临时的解决办法是将按钮填充相同的渐变色。如画的标题栏的五种渐变色的position数组值为
1 float positions[]={ 2 0.0f, 3 0.2f, 4 0.4f, 5 0.6f, 6 0.8f, 7 1.0f 8 };
颜色为
1 Color colors[]={ 2 Color(255,255,255), 3 Color(247,251,255), 4 Color(239,239,247), 5 Color(222,227,231), 6 Color(231,235,239), 7 Color(214,219,222) 8 };
根据坐标计算出按钮的渐变色颜色和位置分别为
1 Color colors[]={ 2 Color(247,251,255), 3 Color(239,239,247), 4 Color(222,227,231), 5 Color(231,235,239), 6 }; 7 float positions[]={ 8 0.0f, 9 0.333333f, 10 0.666666f, 11 1.0f 12 };
这种方法看起来挺笨的,所以最后留两个问题。
问题一:如何设置系统菜单栏为渐变色?
问题二:按钮背景如何透明?
参考:杂七杂八找了很多资料
原文:http://www.cnblogs.com/lanf/p/5039313.html