头文件:CPictureEx用于显示一个等待动画

#pragma once#include"afxwin.h"#include"resource.h"#include"PictureEx.h"#include<thread>

//CWaitDlg 对话框
classCWaitSingleEvent {public:
CWaitSingleEvent()
: handle_(nullptr){
handle_
=CreateEvent(nullptr, TRUE, FALSE, nullptr);
}
~CWaitSingleEvent(){if(handle_) {
CloseHandle(handle_);
}
}
operator bool()const{return handle_ !=nullptr;
}
int Wait(constDWORD wait_time) {
DWORD retval
= 0;if(handle_) {
retval
=WaitForSingleObject(handle_, wait_time);
ResetEvent(handle_);

}
returnretval;
}
voidNotify() {if(handle_) {
SetEvent(handle_);
}
}
protected:
CWaitSingleEvent(
const CWaitSingleEvent&rhs){

}

CWaitSingleEvent
& operator=(const CWaitSingleEvent&rhs){return *this;
}
private:
HANDLE handle_;
};

typedef UINT32 (CDialogEx::
*WaitToExec)(void*param);class CWaitDlg : publicCDialogEx
{
DECLARE_DYNAMIC(CWaitDlg)
public:
CWaitDlg(CWnd
* pParent = NULL); //标准构造函数 virtual ~CWaitDlg();//对话框数据 enum { IDD =IDD_DIALOG4 };//设置执行等待函数 void SetWaitToExec(CWnd* pParent, void* pInnerParam, CDialogEx*pThis, WaitToExec pWaitToExec);private:void*exec_inner_param_;
CDialogEx
*dialog_this;
WaitToExec wait_to_exec_func_pt_;
volatile boolis_quit_thread_;
std::thread
*wait_to_exec_thread_;
CWaitSingleEvent wait_to_exec_condition_;
voidwait_to_exec_callback();protected:virtual void DoDataExchange(CDataExchange* pDX); //DDX/DDV 支持 DECLARE_MESSAGE_MAP()public:virtualBOOL OnInitDialog();
CPictureEx m_show_gif_;
virtual voidOnCancel();virtual voidOnOK();
};

代码实现:

//WaitDlg.cpp : 实现文件//#include"stdafx.h"#include"WaitDlg.h"#include"afxdialogex.h"

//CWaitDlg 对话框
IMPLEMENT_DYNAMIC(CWaitDlg, CDialogEx)

CWaitDlg::CWaitDlg(CWnd
* pParent /*=NULL*/)
: CDialogEx(CWaitDlg::IDD, pParent), wait_to_exec_func_pt_(nullptr), dialog_this(nullptr)
{
is_quit_thread_
= false;
exec_inner_param_
=NULL;
wait_to_exec_thread_
=nullptr;
}

CWaitDlg::
~CWaitDlg()
{
is_quit_thread_
= true;
wait_to_exec_condition_.Notify();
if (nullptr !=wait_to_exec_thread_){if(wait_to_exec_thread_->joinable()) {
wait_to_exec_thread_
->join();
}

wait_to_exec_thread_
=nullptr;
}
}
void CWaitDlg::DoDataExchange(CDataExchange*pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_SHOW_GIF, m_show_gif_);
}


BEGIN_MESSAGE_MAP(CWaitDlg, CDialogEx)
END_MESSAGE_MAP()
//CWaitDlg 消息处理程序 BOOL GetResGifSize(long nResId, LPCTSTR name, long *lnWidth, long *lnHeight)
{
HRSRC hRsrc
=FindResource(NULL, MAKEINTRESOURCE(nResId), name);if (NULL ==hRsrc) {returnFALSE;
}

DWORD dwSize
=SizeofResource(NULL, hRsrc);
HGLOBAL hGlobal
=LoadResource(NULL, hRsrc);if (NULL ==hGlobal) {
CloseHandle(hRsrc);
returnFALSE;
}

unsigned
char* pBuffer = (unsigned char*)LockResource(hGlobal);if (NULL ==pBuffer) {
CloseHandle(hRsrc);
FreeResource(hGlobal);
returnFALSE;
}
//判断是否为GIF文件 if(pBuffer[0] != 0x47 && pBuffer[1] != 0x49 && pBuffer[2] != 0x46 && pBuffer[3] != 0x38){returnFALSE;
}
//读取宽高 for(DWORD i = 4; i < dwSize ; i++)
{
if(pBuffer[i] == 0x00 && pBuffer[i+1] == 0x2c)
{
*lnWidth = (pBuffer[i+7]<<8) | pBuffer[i+6];*lnHeight = (pBuffer[i+9]<<8) | pBuffer[i+8];
UnlockResource(hGlobal);
FreeResource(hGlobal);
returnTRUE;
}
}

UnlockResource(hGlobal);
FreeResource(hGlobal);
returnFALSE;
}

BOOL CWaitDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
//设置窗口大小 long nGifWidth = 75;long nGifHeight = 75;if (!GetResGifSize(IDR_WAIT_GIF_1, _T("GIF"), &nGifWidth, &nGifHeight)){
MessageBox(_T(
"内部错误"),_T("错误"), MB_OK |MB_ICONERROR);
}

RECT rt;
GetClientRect(
&rt);//判断窗口是否太大,或者太小,放不下 if ( (rt.right - rt.left - nGifWidth > 64) || (rt.bottom - rt.top - nGifHeight > 64) ||(rt.right- rt.left < nGifWidth) || (rt.bottom - rt.top <nGifHeight) ) {
RECT rtWin;
GetWindowRect(
&rtWin);//调整窗口大小 rtWin.right = rtWin.left + nGifWidth + 64;
rtWin.bottom
= rtWin.top + nGifHeight + 64;
MoveWindow(
&rtWin);//重新获取客户区大小 GetClientRect(&rt);
}

CenterWindow();
//计算位置 rt.left = (rt.right - rt.left - nGifWidth)/2;
rt.right
= rt.left +nGifWidth;
rt.top
= (rt.bottom - rt.top - nGifHeight)/2;
rt.bottom
= rt.left +nGifHeight;//转化成屏幕坐标//ClientToScreen(&rt); m_show_gif_.MoveWindow(&rt, TRUE);

SetBackgroundColor(RGB(
240,240,240), TRUE);
m_show_gif_.SetBkColor(RGB(
240,240,240));if (m_show_gif_.Load(MAKEINTRESOURCE(IDR_WAIT_GIF_1),_T("GIF"))){
m_show_gif_.Draw();
}
return TRUE; //return TRUE unless you set the focus to a control//异常: OCX 属性页应返回 FALSE }voidCWaitDlg::wait_to_exec_callback()
{
if(is_quit_thread_) {return;
}
while (!is_quit_thread_){//等待事件是否过来 wait_to_exec_condition_.Wait(INFINITE);if(is_quit_thread_) {break;}//判断参数是否OK if ((nullptr != dialog_this) && (nullptr !=wait_to_exec_func_pt_)){
(dialog_this
->*wait_to_exec_func_pt_)(exec_inner_param_);//执行完一次,那就隐藏一下 if (NULL !=m_hWnd)
{
ShowWindow(SW_HIDE);
}
}
}
}
//设置执行等待函数 void CWaitDlg::SetWaitToExec(CWnd* pParent, void* pInnerParam, CDialogEx*pThis, WaitToExec pWaitToExec)
{
exec_inner_param_
=pInnerParam;
dialog_this
=pThis;
wait_to_exec_func_pt_
=pWaitToExec;//通知线程执行 is_quit_thread_ = false;if (wait_to_exec_thread_ ==nullptr) {
wait_to_exec_thread_
= newstd::thread;
}
if(!wait_to_exec_thread_->joinable()) {*wait_to_exec_thread_ = std::move(std::thread(&CWaitDlg::wait_to_exec_callback, this));
}
//显示本窗口 if (NULL ==m_hWnd) {
Create(IDD_DIALOG4, pParent);
}

ShowWindow(SW_SHOW);
//触发事件 wait_to_exec_condition_.Notify();
}
voidCWaitDlg::OnCancel()
{
//TODO: 在此添加专用代码和/或调用基类//CDialogEx::OnCancel(); }voidCWaitDlg::OnOK()
{
//TODO: 在此添加专用代码和/或调用基类//暂时允许关闭 CDialogEx::OnOK();
}

使用示例:

typedef structset_xxx_info_st {intindex;
CString strXxxInfo;
}set_xxx_info_st;
voidCXXXParamDlg::OnClickedBtnWriteXxx()
{
CString strXxxC
= _T("strXxxC");//必须使用堆内存,调用会立即返回,但对象的使用,却在线程中 set_xxx_info_st* inn_param = newset_xxx_info_st;
inn_param
->index = m_set_cert_index_combo_.GetCurSel() + 1;
inn_param
->strXxxInfo.Append(strXxxC);//调用线程接口去获取 m_wait_dlg_.SetWaitToExec(GetParent(), inn_param, this, (WaitToExec)&CXXXParamDlg::WaitToExecSetXXXInfo);
}

UINT32 CXXXParamDlg::WaitToExecSetXXXInfo(
void*inn_param)
{
UINT32 ulRet
= -1;

set_xxx_info_st
* set_param = (set_xxx_info_st*)(inn_param);//禁止父窗口控件 GetParent()->GetParent()->EnableWindow(FALSE);//设置进去 ExecSetXXX(set_param->index, set_param->strXxxInfo);//禁止父窗口控件 GetParent()->GetParent()->EnableWindow(TRUE);if (nullptr !=set_param) {deleteset_param;
}
return 0;
}

 

标签: none

添加新评论