利用多线程让没有窗口的程序显示进度条

介绍:

某些软件打开后,首先会看到数据载入的进度条,而不是主界面。也就是说,无窗口的后台程序在运行,进度条也在改变。   其实这是通过多线程实现的。

原理:

主程序先创建一个线程,该线程接着创建一个进度条,然后主程序开始后台处理,在后台处理期间不断的给进度条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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值