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