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

//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);
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值