用C多线程实现当年微软的竞赛题

来源:互联网 发布:mac bash 改为 user 编辑:程序博客网 时间:2024/06/05 14:42
//1986年微软举行的一场程序设计竞赛/************************************************************************//*竞赛题目是:建立一个包含四个窗口的多任务仿真程序。第一个窗口必须显示一系列的递增数,第二个必须/*显示一系列的递增质数,而第三个必须显示Fibonacci数列(Fibonacci数列以数字0和1开始,后/*头每一个数都是其前两个数的和-即0、1、1、2、3、5、8等等)。这三个窗口应该在数字达到窗/*口底部时或者进行滚动,或者自行清除窗口内容。第四个窗口必须显示任意半径的圆,而程序必须/*在按下一个Esc键时终止。                                                                  /************************************************************************//************************************************************************//* 这里采用多线程编写这个程序,程序在VS2005中编译运行通过                                                                  /************************************************************************///引入头文件#include <Windows.h>#include <math.h>#include "process.h"//定义一个结构体,存放窗口句柄、窗口的宽度和高度、字符的高度和名为bKill的布尔变量typedef struct { HWND hwnd; int cxClient; int cyClient; int cyChar; BOOL bKill;}PARAMS,*PPARAMS;//声明窗口过程函数(回调函数)LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);//程序主方法int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow){ static TCHAR szAppName[] = TEXT("Mulit"); HWND hwnd; MSG msg; //定义一个窗口类(窗口类是一个结构体) WNDCLASS wndclass;  //填充窗口类的各个字段 wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName;  //注册窗口函数 if(!RegisterClass(&wndclass)){  MessageBox(NULL,TEXT("this program requires windows NT!"),szAppName,MB_ICONERROR);  return 0; }  //创建窗口 hwnd = CreateWindow(szAppName,szAppName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,400,400,NULL,NULL,hInstance,NULL); //显示窗口 ShowWindow(hwnd,iCmdShow); //更新窗口 UpdateWindow(hwnd); //著名的消息循环 while(GetMessage(&msg,NULL,0,0)){  TranslateMessage(&msg);  DispatchMessage(&msg); } return msg.wParam;}//当字符填满子窗口时重绘int CheckBottom(HWND hwnd,int cyClient,int cyChar, int iLine){ if(iLine * cyChar + cyChar > cyClient){  InvalidateRect(hwnd,NULL,TRUE);  UpdateWindow(hwnd);  iLine = 0; } return iLine;}/************************************************************************//* Window 1:用来显示一串递增数(从1开始)  线程一                                                             /************************************************************************/void Thread1(PVOID pvoid){ HDC hdc; int iNum = 0,iLine = 0; PPARAMS pparams; TCHAR szBuffer[16]; pparams = (PPARAMS)pvoid; while(!pparams->bKill){  if(iNum < 0){   iNum = 0;  }  iLine = CheckBottom(pparams->hwnd,pparams->cyClient,pparams->cyChar,iLine);  hdc = GetDC(pparams->hwnd);  TextOut(hdc,0,iLine * pparams->cyChar,szBuffer,wsprintf(szBuffer,TEXT("%d"),iNum++));  ReleaseDC(pparams->hwnd,hdc);  iLine++;  Sleep(2000); } _endthread();}LRESULT CALLBACK WndProc1(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ static PARAMS params; switch (message){  case WM_CREATE:   params.hwnd = hwnd;   params.cyChar = HIWORD(GetDialogBaseUnits());   _beginthread(Thread1,0,¶ms);   return 0;  case WM_SIZE:   params.cyClient = HIWORD(lParam);   return 0;  case WM_DESTROY:   params.bKill = TRUE;   return 0; } return DefWindowProc(hwnd,message,wParam,lParam);}/************************************************************************//* Window 2:用来显示一串递增的质数  线程二                                                                  /************************************************************************/void Thread2(PVOID pvoid){ HDC hdc; int iNum = 1,iLine = 0,i,iSqrt; PPARAMS pparams; TCHAR szBuffer[16];  pparams = (PPARAMS)pvoid; while(!pparams->bKill){  do{   if(++iNum<0){    iNum = 0;   }   iSqrt = (int)sqrt(double(iNum));   for(i = 2;i<=iSqrt;i++){    if(iNum%i == 0){     break;    }   }  } while (i<=iSqrt);  iLine = CheckBottom(pparams->hwnd,pparams->cyClient,pparams->cyChar,iLine);  hdc = GetDC(pparams->hwnd);  TextOut(hdc,0,iLine * pparams->cyChar,szBuffer,wsprintf(szBuffer,TEXT("%d"),iNum));  ReleaseDC(pparams->hwnd,hdc);  iLine++;  Sleep(2000); } _endthread();}LRESULT CALLBACK WndProc2(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ static PARAMS params; switch(message){  case WM_CREATE:   params.hwnd=hwnd;   params.cyChar = HIWORD(GetDialogBaseUnits());   _beginthread(Thread2,0,¶ms);   return 0;  case WM_SIZE:   params.cyClient = HIWORD(lParam);   return 0;  case WM_DESTROY:   params.bKill = TRUE;   return 0; } return DefWindowProc(hwnd,message,wParam,lParam);}/************************************************************************//* Window 3:用来显示Fibonacci数列 0,1,1,2,3,5,8,13,21,34......  线程三                                                                  /************************************************************************/void Thread3(PVOID pvoid){ HDC hdc; int iNum = 0,iNext = 1,iLine = 0,iTemp; PPARAMS pparams; TCHAR szBuffer[16]; pparams = (PPARAMS)pvoid; while(!pparams->bKill){  if(iNum<0){   iNum = 0;   iNext = 1;  }  iLine = CheckBottom(pparams->hwnd,pparams->cyClient,pparams->cyChar,iLine);    hdc = GetDC(pparams->hwnd);  TextOut(hdc,0,iLine * pparams->cyChar,szBuffer,wsprintf(szBuffer,TEXT("%d"),iNum));  ReleaseDC(pparams->hwnd,hdc);  iTemp = iNum;  iNum = iNext+iNum;  iNext = iTemp;  iLine++;  Sleep(2000); } _endthread();}LRESULT CALLBACK WndProc3(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ static PARAMS params; switch(message){  case WM_CREATE:   params.hwnd = hwnd;   params.cyChar = HIWORD(GetDialogBaseUnits());   _beginthread(Thread3,0,¶ms);   return 0;  case WM_SIZE:   params.cyClient = HIWORD(lParam);   return 0;  case WM_DESTROY:   params.bKill = TRUE;   return 0; } return DefWindowProc(hwnd,message,wParam,lParam);}/************************************************************************//* Window 4:用来画出随机半径的圆  线程四                                                                  /************************************************************************/void Thread4(PVOID pvoid){ HDC hdc; int iDiameter; PPARAMS pparams; pparams = (PPARAMS)pvoid; while(!pparams->bKill){  InvalidateRect(pparams->hwnd,NULL,TRUE);  UpdateWindow(pparams->hwnd);  iDiameter = rand()%(max(1,min(pparams->cxClient,pparams->cyClient)));  hdc = GetDC(pparams->hwnd);  Ellipse(hdc,(pparams->cxClient-iDiameter)/2,(pparams->cyClient-iDiameter)/2,(pparams->cxClient+iDiameter)/2,(pparams->cyClient+iDiameter)/2);  ReleaseDC(pparams->hwnd,hdc);  Sleep(2000); } _endthread();}LRESULT CALLBACK WndProc4(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ static PARAMS params; switch(message){  case WM_CREATE:   params.hwnd = hwnd;   params.cyChar = HIWORD(GetDialogBaseUnits());   _beginthread(Thread4,0,¶ms);   return 0;  case WM_SIZE:   params.cxClient = LOWORD(lParam);   params.cyClient = HIWORD(lParam);   return 0;  case WM_DESTROY:   params.bKill = TRUE;   return 0; } return DefWindowProc(hwnd,message,wParam,lParam);}/************************************************************************//* Main Window:用来创建子窗口                                                                  /************************************************************************/LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ static HWND hwndChild[4]; static TCHAR * szChildClass[] = {TEXT("Child1"),TEXT("Child2"),TEXT("Child3"),TEXT("Child4")}; static WNDPROC ChildProc[] = {WndProc1,WndProc2,WndProc3,WndProc4}; HINSTANCE hInstance; int i,cxClient,cyClient; WNDCLASS wndclass; switch(message){  case WM_CREATE:   hInstance = (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE);   wndclass.style = CS_HREDRAW | CS_VREDRAW;   wndclass.cbClsExtra = 0;   wndclass.cbWndExtra = 0;   wndclass.hInstance = hInstance;   wndclass.hIcon = NULL;   wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);   wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);   wndclass.lpszMenuName = NULL;   for(i=0;i<4;i++){    wndclass.lpfnWndProc = ChildProc[i];    wndclass.lpszClassName = szChildClass[i];    RegisterClass(&wndclass);    hwndChild[i] = CreateWindow(szChildClass[i],NULL,WS_CHILDWINDOW|WS_BORDER|WS_VISIBLE,0,0,0,0,hwnd,(HMENU)i,hInstance,NULL);   }   return 0;  case WM_SIZE:   cxClient = LOWORD(lParam);   cyClient = HIWORD(lParam);   for(i=0;i<4;i++){    MoveWindow(hwndChild[i],(i%2)*cxClient/2,(i>1)*cyClient/2,cxClient/2,cyClient/2,TRUE);   }   return 0;  case WM_CHAR:   //判断是否按下ESC键(此处是键盘虚拟码、十六进制)   if(wParam == '\x1B'){    DestroyWindow(hwnd);   }   return 0;  case WM_DESTROY:   PostQuitMessage(0);   return 0; } return DefWindowProc(hwnd,message,wParam,lParam);}