利用多线程让没有窗口的程序显示进度条
2007-06-05 17:14
337 查看
介绍:
某些软件打开后,首先会看到数据载入的进度条,而不是主界面。也就是说,无窗口的后台程序在运行,进度条也在改变。 其实这是通过多线程实现的。
原理:
主程序先创建一个线程,该线程接着创建一个进度条,然后主程序开始后台处理,在后台处理期间不断的给进度条SendMessage,来改变进度。
IDD_DIALOG1 和 IDC_PROGRESS1 是资源中的窗口和进度条的ID。
#include
<
windows.h
>
#include
"
resource.h
"
#include
<
process.h
>
#include
<
commctrl.h
>
#pragma comment (lib,
"
comctl32.lib
"
)
#define WM_DLGCREATED WM_USER
+
1
//
#define WM_PROGRESS WM_USER+2
typedef struct
{
HWND hDlg;
HANDLE hDlgCreatedEvent;
HWND hProgress;
HINSTANCE hInst;
}MyParams,
*
ptMyParams;
/*
-----------------------------------------------------------------------
*/
BOOL CALLBACK MyDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
void
Thread1(PVOID pvoid);
/*
------------------------------------------------------------------------
*/
void
Thread1(PVOID pvoid)
{
ptMyParams pt
=
(ptMyParams)pvoid;
DialogBoxParam(pt
->
hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, MyDlgProc, (LPARAM)pt);
_endthread();
}
/*
------------------------------------------------------------------------
*/
BOOL CALLBACK MyDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
ptMyParams pt;
switch
(Message)
{
case
WM_INITDIALOG:
pt
=
(ptMyParams)lParam;
pt
->
hDlg
=
hWnd;
pt
->
hProgress
=
GetDlgItem(hWnd, IDC_PROGRESS1);
PostMessage(hWnd, WM_DLGCREATED,
0
, lParam);
return
TRUE;
case
WM_DLGCREATED:
pt
=
(ptMyParams)lParam;
SetEvent(pt
->
hDlgCreatedEvent);
//
信号置位(1)
return
TRUE;
}
return
FALSE;
}
/*
------------------------------------------------------------------------
*/
int
APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int
nCmdShow)
{
static
MyParams myParam;
//
静态变量
int
i;
INITCOMMONCONTROLSEX initcontrols;
initcontrols.dwSize
=
sizeof(INITCOMMONCONTROLSEX);
initcontrols.dwICC
=
ICC_PROGRESS_CLASS;
InitCommonControlsEx(
&
initcontrols);
myParam.hInst
=
hInstance;
myParam.hDlgCreatedEvent
=
CreateEvent(NULL, FALSE, FALSE, NULL);
//
初始化信号(0)
//
传入要使用的变量地址,而不能在另一线程中直接使用全局变量
_beginthread(Thread1,
0
,
&
myParam);
WaitForSingleObject(myParam.hDlgCreatedEvent, INFINITE);
//
等待信号置位(1)
CloseHandle(myParam.hDlgCreatedEvent);
//
删除Handle
myParam.hDlgCreatedEvent
=
0
;
SendMessage(myParam.hProgress, PBM_SETRANGE,
0
, MAKELPARAM(
0
,
30
));
for
(i
=
0
;i
<
30
;i
++
)
{
SendMessage(myParam.hProgress, PBM_SETPOS, i,
0
);
Sleep(
50
);
}
Sleep(
500
);
EndDialog(myParam.hDlg,
0
);
return
0
;
}
注意:
1. 必须使用信号,待窗口创建之后才能给进度条SendMessage。否则窗口可能无法显示,或出现其它问题。
2. 不能直接在线程中使用全局变量,必须通过参数传递该变量指针。该指针被传给了线程入口函数的参数pvoid。
某些软件打开后,首先会看到数据载入的进度条,而不是主界面。也就是说,无窗口的后台程序在运行,进度条也在改变。 其实这是通过多线程实现的。
原理:
主程序先创建一个线程,该线程接着创建一个进度条,然后主程序开始后台处理,在后台处理期间不断的给进度条SendMessage,来改变进度。
IDD_DIALOG1 和 IDC_PROGRESS1 是资源中的窗口和进度条的ID。
#include
<
windows.h
>
#include
"
resource.h
"
#include
<
process.h
>
#include
<
commctrl.h
>
#pragma comment (lib,
"
comctl32.lib
"
)
#define WM_DLGCREATED WM_USER
+
1
//
#define WM_PROGRESS WM_USER+2
typedef struct
{
HWND hDlg;
HANDLE hDlgCreatedEvent;
HWND hProgress;
HINSTANCE hInst;
}MyParams,
*
ptMyParams;
/*
-----------------------------------------------------------------------
*/
BOOL CALLBACK MyDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
void
Thread1(PVOID pvoid);
/*
------------------------------------------------------------------------
*/
void
Thread1(PVOID pvoid)
{
ptMyParams pt
=
(ptMyParams)pvoid;
DialogBoxParam(pt
->
hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, MyDlgProc, (LPARAM)pt);
_endthread();
}
/*
------------------------------------------------------------------------
*/
BOOL CALLBACK MyDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
ptMyParams pt;
switch
(Message)
{
case
WM_INITDIALOG:
pt
=
(ptMyParams)lParam;
pt
->
hDlg
=
hWnd;
pt
->
hProgress
=
GetDlgItem(hWnd, IDC_PROGRESS1);
PostMessage(hWnd, WM_DLGCREATED,
0
, lParam);
return
TRUE;
case
WM_DLGCREATED:
pt
=
(ptMyParams)lParam;
SetEvent(pt
->
hDlgCreatedEvent);
//
信号置位(1)
return
TRUE;
}
return
FALSE;
}
/*
------------------------------------------------------------------------
*/
int
APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int
nCmdShow)
{
static
MyParams myParam;
//
静态变量
int
i;
INITCOMMONCONTROLSEX initcontrols;
initcontrols.dwSize
=
sizeof(INITCOMMONCONTROLSEX);
initcontrols.dwICC
=
ICC_PROGRESS_CLASS;
InitCommonControlsEx(
&
initcontrols);
myParam.hInst
=
hInstance;
myParam.hDlgCreatedEvent
=
CreateEvent(NULL, FALSE, FALSE, NULL);
//
初始化信号(0)
//
传入要使用的变量地址,而不能在另一线程中直接使用全局变量
_beginthread(Thread1,
0
,
&
myParam);
WaitForSingleObject(myParam.hDlgCreatedEvent, INFINITE);
//
等待信号置位(1)
CloseHandle(myParam.hDlgCreatedEvent);
//
删除Handle
myParam.hDlgCreatedEvent
=
0
;
SendMessage(myParam.hProgress, PBM_SETRANGE,
0
, MAKELPARAM(
0
,
30
));
for
(i
=
0
;i
<
30
;i
++
)
{
SendMessage(myParam.hProgress, PBM_SETPOS, i,
0
);
Sleep(
50
);
}
Sleep(
500
);
EndDialog(myParam.hDlg,
0
);
return
0
;
}
注意:
1. 必须使用信号,待窗口创建之后才能给进度条SendMessage。否则窗口可能无法显示,或出现其它问题。
2. 不能直接在线程中使用全局变量,必须通过参数传递该变量指针。该指针被传给了线程入口函数的参数pvoid。
相关文章推荐
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(二)
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(一)
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(一)_转
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(一)-asp.net关注
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(二)
- 利用C#线程窗口调试多线程程序
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(一)
- 利用WinInet和多线程实现实时显示的下载进度条
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(二)_转
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(1,2)
- asp.net利用多线程执行长时间的任务,在客户端显示进度条
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(一)
- 利用C#线程窗口调试多线程程序
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(一)
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例
- asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例