1 #include <Windows.h> 2 #include <tchar.h> 3 #include <math.h> 4 BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow); 5 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 6 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 7 { 8 MSG msg; 9 if (!InitWindowClass(hInstance, nCmdShow)) 10 { 11 MessageBox(NULL, L"創建窗口失敗!", _T("創建窗口"), NULL); 12 return 1; 13 } 14 while (GetMessage(&msg, NULL, 0, 0)) 15 { 16 TranslateMessage(&msg); 17 DispatchMessage(&msg); 18 } 19 return(int)msg.wParam; 20 } 21 22 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 23 { 24 HDC hDC; 25 PAINTSTRUCT ps; 26 HBRUSH hBrush; 27 HPEN hPen; 28 RECT clientRect; 29 static RECT oldClientRect = { 0, 0, 0, 0 }; 30 float sita = 0; 31 int a[4] = { 75, 50, 60, 90 }, maxValue, i, xOrg, yOrg, deltaX, deltaY, xBegin, yBegin, xEnd, yEnd, s = 0; 32 int hatchBrushStyle[4] = { HS_BDIAGONAL, HS_FDIAGONAL, HS_CROSS, HS_DIAGCROSS }; //四個陰影樣式 33 COLORREF colorIndex[4] = { RGB(255, 0, 0), RGB(0, 255, 0), RGB(0, 0, 255), RGB(255, 0, 255) }; //四種顏色 34 switch (message) 35 { 36 case WM_PAINT: 37 maxValue = a[0]; 38 for (i = 0; i < 4; i++) 39 { 40 s += a[i]; 41 if (a[i]>maxValue) 42 maxValue = a[i]; 43 } //計算所有數據總值和最大值 44 hDC = BeginPaint(hWnd, &ps); 45 GetClientRect(hWnd, &clientRect); //獲取用戶區的尺寸 46 if ((clientRect.right - clientRect.left) < 300 || (clientRect.bottom - clientRect.top) < 300) //判斷屏幕尺寸 47 { 48 MessageBox(hWnd, L"屏幕尺寸大小,無法繪圖!", L"錯誤信息", 0); 49 //EndPaint(hWnd, &ps); //結束繪圖 50 break; 51 } 52 hPen = (HPEN)GetStockObject(BLACK_PEN); //設置畫筆為系統預定義的黑色畫筆 53 SelectObject(hDC, hPen); //選擇畫筆 54 Rectangle(hDC, clientRect.left + 10, clientRect.top + 10, clientRect.right - 10, clientRect.bottom - 10); 55 MoveToEx(hDC, (clientRect.left + clientRect.right) / 2, clientRect.top + 10, NULL); 56 LineTo(hDC, (clientRect.left + clientRect.right) / 2, clientRect.bottom - 10); //從窗口的中間將窗口分為左右兩部分 57 //------------------------------以下是在左半部分用柱形圖表示的數據分布圖------------------------------ 58 xOrg = clientRect.left + 60; 59 yOrg = clientRect.bottom - 60; //柱形圖的坐標原點 60 xEnd = (clientRect.left + clientRect.right) / 2 - 50; //坐標軸的最右邊 61 yEnd = yOrg; 62 deltaX = (xEnd - xOrg - 100) / 4; //計算水平坐標的單位像素 63 MoveToEx(hDC, xOrg, yOrg, NULL); 64 LineTo(hDC, xEnd, yEnd); //畫水平坐標軸 65 xEnd = xOrg; 66 yEnd = clientRect.top + 60; //坐標軸的最上邊 67 MoveToEx(hDC, xOrg, yOrg, NULL); 68 LineTo(hDC, xEnd, yEnd); //畫垂直坐標軸 69 deltaY = (yOrg - yEnd - 100) / maxValue; //計算垂直坐標的單位像素 70 hPen = CreatePen(PS_SOLID, 1, RGB(127, 127, 127)); //用灰色作為畫筆 71 SelectObject(hDC, hPen); //選擇畫筆 72 for (i = 0; i < 4; i++) 73 { 74 hBrush = CreateHatchBrush(hatchBrushStyle[i], colorIndex[i]); //創建帶陰影的畫刷 75 SelectObject(hDC, hBrush); //選擇畫刷 76 xBegin = xOrg + deltaX*i; 77 yBegin = yOrg; 78 xEnd = xBegin + deltaX; 79 yEnd = yOrg - a[i] * deltaY; 80 Rectangle(hDC, xBegin, yBegin, xEnd, yEnd); //每一部分的柱形圖 81 } 82 //------------------------------以下是在右半部分用餅圖表示的數據分布圖------------------------------ 83 xOrg = clientRect.left + (clientRect.right - clientRect.left) * 3 / 4 + 10; 84 yOrg = clientRect.top + (clientRect.bottom - clientRect.top) / 2 + 10; //xOrg,yOrg為右半部分的中心點坐標 85 deltaX = deltaY = min((clientRect.right - clientRect.left) / 4, (clientRect.bottom - clientRect.top) / 2) - 50; 86 xBegin = xOrg + 10; 87 yBegin = yOrg; 88 for (i = 0; i < 4; i++) 89 { 90 hBrush = CreateSolidBrush(colorIndex[i]); //創建單色的畫刷 91 SelectObject(hDC, hBrush); //選擇畫刷 92 sita = sita + 2 * 3.1415*a[i] / s; 93 xEnd = xOrg + 10 * cos(sita); 94 yEnd = yOrg - 10 * sin(sita); //計算餅圖終點的坐標 95 Pie(hDC, xOrg - deltaX, yOrg - deltaY, xOrg + deltaX, yOrg + deltaY, xBegin, yBegin, xEnd, yEnd);//各部分餅圖 96 xBegin = xEnd; 97 yBegin = yEnd; //下次餅圖起點的坐標 98 } 99 DeleteObject(hPen); 100 DeleteObject(hBrush); 101 EndPaint(hWnd, &ps); //結束繪圖 102 break; 103 case WM_SIZE: //窗口尺寸發生變化時,應刷新窗口 104 InvalidateRect(hWnd, NULL, true); 105 break; 106 case WM_DESTROY: 107 PostQuitMessage(0); //調用PostQuitMessage發出WM_QUIT消息 108 break; 109 default: 110 return DefWindowProc(hWnd, message, wParam, lParam); //默認時采用系統消息默認處理函數 111 break; 112 } 113 return 0; 114 } 115 BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow) 116 { 117 WNDCLASSEX wcex; 118 HWND hWnd; 119 TCHAR szWindowClass[] = L"窗口示例"; 120 TCHAR szTitle[] = L"柱形圖及餅圖顯示數據統計"; 121 wcex.cbSize = sizeof(WNDCLASSEX); 122 wcex.style = 0; 123 wcex.lpfnWndProc = WndProc; 124 wcex.cbClsExtra = 0; 125 wcex.cbWndExtra = 0; 126 wcex.hInstance = hInstance; 127 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); 128 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 129 wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 130 wcex.lpszMenuName = NULL; 131 wcex.lpszClassName = szWindowClass; 132 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); 133 if (!RegisterClassEx(&wcex)) 134 return FALSE; 135 hWnd = CreateWindow( 136 szWindowClass, 137 szTitle, 138 WS_OVERLAPPEDWINDOW, 139 CW_USEDEFAULT, CW_USEDEFAULT, 140 CW_USEDEFAULT, CW_USEDEFAULT, 141 NULL, 142 NULL, 143 hInstance, 144 NULL 145 ); 146 if (!hWnd) 147 return FALSE; 148 ShowWindow(hWnd, nCmdShow); 149 UpdateWindow(hWnd); 150 return TRUE; 151 }