📄 sample13.c
字号:
#include <windows.h>
#include <formatio.h>
#include "inifile.h"
#include <ansi_c.h>
#include <cvirte.h>
#include <utility.h>
#include <userint.h>
#include <stdio.h>
#include "sample13.h"
#include <libsupp.h>
#include <math.h>
//最多创建的线程数
#define MAXTHREADS 6
#define RADIUS 40
typedef struct tag_THREAD_INFO{
int ctrlID; // Cavas控件ID号
HANDLE hThread; //线程句柄
unsigned int CurrentValue; //线程当前值
int IsRunning; //线程状态
} THREAD_INFO;
static int panelHandle = 0;
static volatile int exiting = 0;
//变量数组threadInfoArray储存各线程信息
THREAD_INFO threadInfoArray[MAXTHREADS] ;
//变量threadCount表示当前已创建线程数
int threadCount = 0;
//数组top 和left分别表示各线程Cavas控件的位置
int top[MAXTHREADS]={40,40,40,180,180,180};
int left[MAXTHREADS]={20,140,260,20,140,260};
int color;
Point start,end;
//INI文本数据
IniText myInifile;
int ShutdownApplication(void);
DWORD WINAPI MyThread(LPVOID item);
int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
//习题添加的代码
int status;
int threadStatus[MAXTHREADS];
//添加代码结束
int i,num;
for(i=0;i<MAXTHREADS;i++)
threadInfoArray[i].IsRunning=-1;
if (InitCVIRTE (hInstance, 0, 0) == 0)
return -1;
if ((panelHandle = LoadPanel (0, "sample13.uir", PANEL)) < 0)
return -1;
//创建列表
if (!(myInifile = Ini_New (0)))
{
//创建失败,显示出错信息并退出
MessagePopup("Inifile","Error allocating memory for Inifile");
return 0;
}
//从sample13.ini文件中读取数据到列表
if (!Ini_ReadFromFile (myInifile, "sample13.ini"))
{
//读取数据成功
//从列表中读取上次程序关闭时的线程数
Ini_GetInt (myInifile, "ThreadInfo", "threadNum", &num);
if(num<0) num=0;
if(num>6) num=6;
//习题添加的代码
//从列表中读取上次程序关闭时的线程状态
Ini_GetInt (myInifile, "ThreadInfo", "thread1", &threadStatus[0]);
Ini_GetInt (myInifile, "ThreadInfo", "thread2", &threadStatus[1]);
Ini_GetInt (myInifile, "ThreadInfo", "thread3", &threadStatus[2]);
Ini_GetInt (myInifile, "ThreadInfo", "thread4", &threadStatus[3]);
Ini_GetInt (myInifile, "ThreadInfo", "thread5", &threadStatus[4]);
Ini_GetInt (myInifile, "ThreadInfo", "thread6", &threadStatus[5]);
//添加代码结束
//循环调用CreateCallback函数num次
for(i=0;i<num;i++)
CreateCallback (panelHandle, PANEL_CREATE, EVENT_COMMIT,
NULL, 0, 0);
//习题添加的代码
//设置线程状态,暂停或者运行
for(i=0;i<num;i++)
if(threadStatus[i]==0)
{
status=SuspendThread(threadInfoArray[i].hThread);
if(status<0)
MessagePopup ("Error", "Suspend thread error!");
else
threadInfoArray[i].IsRunning=0;
}
RingCallback (panelHandle, PANEL_RING, EVENT_COMMIT,0,0,0);
//添加代码结束
}
DisplayPanel (panelHandle);
RunUserInterface ();
//将线程数储存到列表中
Ini_PutInt (myInifile, "ThreadInfo", "threadNum", threadCount);
//习题添加的代码
//将线程状态储存到列表中
Ini_PutInt (myInifile, "ThreadInfo", "thread1", threadInfoArray[0].IsRunning);
Ini_PutInt (myInifile, "ThreadInfo", "thread2", threadInfoArray[1].IsRunning);
Ini_PutInt (myInifile, "ThreadInfo", "thread3", threadInfoArray[2].IsRunning);
Ini_PutInt (myInifile, "ThreadInfo", "thread4", threadInfoArray[3].IsRunning);
Ini_PutInt (myInifile, "ThreadInfo", "thread5", threadInfoArray[4].IsRunning);
Ini_PutInt (myInifile, "ThreadInfo", "thread6", threadInfoArray[5].IsRunning);
//添加代码结束
//将列表的数据储存到INI文件中
Ini_WriteToFile (myInifile, "sample13.ini");
//在退出程序前终止已创建的线程
ShutdownApplication();
return 0;
}
int CVICALLBACK CreateCallback (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
//定义变量
char threadName[50];
int ctrlID;
DWORD threadID;
switch (event) {
case EVENT_COMMIT:
//判断是否已经创建了6个线程
if (threadCount==MAXTHREADS)
{
//显示出错信息,并返回
MessagePopup ("Error", "Maximal threads has createed!");
return 0;
}
//创建新线程,MyThread为线程函数,其定义稍后介绍
threadInfoArray[threadCount].hThread = CreateThread(
NULL, 0,
(LPTHREAD_START_ROUTINE)MyThread,
(LPVOID)threadCount, 0,
(LPDWORD)&threadID);
//创建线程是否成功
if (threadInfoArray[threadCount].hThread)
{
//创建线程成功
//创建新Cavas控件
sprintf(threadName, "Thread %d", threadCount+1);
threadInfoArray[threadCount].ctrlID =
NewCtrl (panel, CTRL_CANVAS, threadName, top[threadCount],
left[threadCount]);
//设置threadInfoArray相关参数
threadInfoArray[threadCount].IsRunning=1;
threadInfoArray[threadCount].CurrentValue=0;
//已创建线程数加1
threadCount++;
//向控件RING添加新项目
InsertListItem (panel, PANEL_RING, -1, threadName, threadCount);
//设置RESUMEORSUSPEND控件值为0
SetCtrlVal (panel, PANEL_RESUMEORSUSPEND, 0);
//如果是创建第一个线程,设置TERMINATE
//RING、RESUMEORSUSPEND控件有效
if(threadCount==1)
{
SetCtrlAttribute (panel, PANEL_TERMINATE, ATTR_DIMMED, 0);
SetCtrlAttribute (panel, PANEL_RING, ATTR_DIMMED, 0);
SetCtrlAttribute (panel, PANEL_RESUMEORSUSPEND, ATTR_DIMMED, 0);
}
}
else
//创建线程失败,显示出错信息
MessagePopup ("Error", "Creating thread fail!");
break;
}
return 0;
}
//在退出程序前调用该函数关闭已运行线程
int ShutdownApplication(void)
{
int index=0 , exitCode;
double startTime;
exiting = 1;
for(index=0;index<MAXTHREADS;index++)
{
if(threadInfoArray[index].hThread)
{
if(!threadInfoArray[index].IsRunning)
ResumeThread(threadInfoArray[index].hThread);
startTime=Timer();
GetExitCodeThread(threadInfoArray[index].hThread, &exitCode);
while ((exitCode==STILL_ACTIVE) && ((Timer()-startTime) < 10.0))
{
Sleep(0);
GetExitCodeThread(threadInfoArray[index].hThread, &exitCode);
}
if (exitCode == STILL_ACTIVE)
TerminateThread(threadInfoArray[index].hThread, 0);
CloseHandle(threadInfoArray[index].hThread);
threadInfoArray[index].hThread = 0;
}
}
return 0;
}
//线程函数,线程运行时执行该函数,
//该函数实现在CANVAS上显示彩色旋转器
DWORD WINAPI MyThread(LPVOID item)
{
while(!exiting){
threadInfoArray[(int)item].CurrentValue++;
if(InStandaloneExecutable())
{
if(threadInfoArray[(int)item].hThread)
{
threadInfoArray[(int)item].CurrentValue+=5;
if(threadInfoArray[(int)item].CurrentValue>360)
threadInfoArray[(int)item].CurrentValue-=360;
start.x=25;
start.y=25;
end.x=(int)(RADIUS*
cos(PI*(threadInfoArray[(int)item].CurrentValue)/180.0)+RADIUS);
end.y=(int)(RADIUS*
sin(PI*(threadInfoArray[(int)item].CurrentValue)/180.0)+RADIUS);;
color = MakeColor(255*rand()/RAND_MAX,
255*rand()/RAND_MAX, 255*rand()/RAND_MAX);
SetCtrlAttribute (panelHandle, threadInfoArray[(int)item].ctrlID,
ATTR_PEN_COLOR, color);
CanvasDrawLine (panelHandle, threadInfoArray[(int)item].ctrlID, start,
end);
}
}
Sleep(0);
}
return(0);
}
int CVICALLBACK TerminateCallback (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
int status,index;
switch (event)
{
case EVENT_COMMIT:
//判断当前是否存在线程
if(threadCount>0)
{
//终止最新创建的线程
status=TerminateThread(threadInfoArray[threadCount-1].hThread,0);
if(status==FALSE)
//操作失败,显示出错信息
MessagePopup ("Error", "Terminate thread error!");
else
{
//终止线程成功
//删除该线程的Canvas控件
DiscardCtrl (panel, threadInfoArray[threadCount-1].ctrlID);
threadInfoArray[threadCount-1].IsRunning=-1;
//删除RING控件中表示该线程的项
GetIndexFromValue (panel, PANEL_RING, &index, threadCount);
DeleteListItem (panel, PANEL_RING, index, 1);
//当前线程数减一
threadCount--;
//如果线程数为0,设置控件TERMINATE、
//RING、RESUMEORSUSPEND无效
if(threadCount==0)
{
SetCtrlAttribute (panel, PANEL_TERMINATE, ATTR_DIMMED, 1);
SetCtrlAttribute (panel, PANEL_RING, ATTR_DIMMED, 1);
SetCtrlAttribute (panel, PANEL_RESUMEORSUSPEND, ATTR_DIMMED, 1);
}
}
}
break;
}
return 0;
}
int CVICALLBACK ResumeOrSuspendCallback (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
int value,status,style;
switch (event)
{
case EVENT_COMMIT:
//获取控件RING和RESUMEORSUSPEND的值
GetCtrlVal (panel, PANEL_RING, &value);
GetCtrlVal (panel, PANEL_RESUMEORSUSPEND, &style);
//判断是暂停还是继续线程
if(style)
{
//暂停线程
status=SuspendThread(threadInfoArray[value-1].hThread);
if(status<0)
//操作失败,显示出错信息
MessagePopup ("Error", "Suspend thread error!");
else
//储存线程状态
threadInfoArray[value-1].IsRunning=0;
}
else
{
//继续线程
status=ResumeThread(threadInfoArray[value-1].hThread);
if(status<0)
//操作失败,显示出错信息
MessagePopup ("Error", "Resume thread error!");
else
//储存线程状态
threadInfoArray[value-1].IsRunning=1;
}
break;
}
return 0;
}
int CVICALLBACK RingCallback (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
int value;
switch (event)
{
case EVENT_COMMIT:
//获取RING控件的值
GetCtrlVal (panel, PANEL_RING, &value);
//根据IsRunning值设置RESUMEORSUSPEND控件的值
if(threadInfoArray[value-1].IsRunning)
SetCtrlVal (panel, PANEL_RESUMEORSUSPEND, 0);
else
SetCtrlVal (panel, PANEL_RESUMEORSUSPEND, 1);
break;
}
return 0;
}
int CVICALLBACK PanelCallback (int panel, int event, void *callbackData,
int eventData1, int eventData2)
{
switch (event)
{
case EVENT_CLOSE:
QuitUserInterface (0);
break;
}
return 0;
}
int CVICALLBACK QuitCallback (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2) {
switch (event) {
case EVENT_COMMIT:
QuitUserInterface (0);
break;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -