http://blog.csdn.net/lanyzh0909/archive/2010/08/20/5827354.aspx
在Windows XP 中实现半透明效果并不是件难事,仅仅只需要调SetLayeredWindowAttributes函数即可。如果同样的效果也想在Windows CE 中重现呢?因为Windows CE没有SetLayeredWindowAttributes 函数,不过在Windows CE 5.0开始支持AlphaBlend,该函数的作用是将两个HDC根据一定的比例混合,即有了类似半透明的效果。
知道了有这个函数,我们现在就应该来看看这个函数怎么用。查阅MSDN,该函数定义为:
BOOL AlphaBlend(
HDC hdcDest,// 指向目标设备环境的句柄
int nXOriginDest,// 指定目目标矩形区域左上角的X轴坐标
int nYOriginDest,// 指定目标矩形区域左上角的Y轴坐标
int nWidthDest,// 指定目标矩形区域的宽度
int nHeightDest,// 指向目标矩形区域高度的句柄
HDC hdcSrc, //指向源设备环境的句柄
int nXOriginSrc,// 指定源矩形区域左上角的X轴坐标
int nYOriginSrc,// 指定源矩形区域左上角的Y轴坐标
int nWidthSrc,// 指定源矩形区域的宽度
int nHeightSrc,// 指定源矩形区域的高度
BLENDFUNCTION blendFunction //指定用于源位图和目标位图使用的alpha混合功能
);
要能想正常的使用这个函数还必须做一件事件将Windows.h和Coredll.lib加载到你的工程里去。
做好了这些事情钱准备了,可以编译你工程的了。幸运的话能够顺利通过编写,不幸的话将出现下列提示错误:
“error C3861: 'AlphaBlend': identifier not found”函数没有定义,是不是很奇怪我们明明把头文件和Library都包含到我们的工程里怎么会没有定义呢?是不是很纳闷?
不要郁闷,那不是你的工程的问题而是系统的问题!在定制WINCE系统DE 时候有一个选项需要注意:如下图:
如果你想用AlphaBlend来绘制透明效果就必须将这一项选上。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
WINCE 下创建动态显示图片窗口
在WINCE下创建一个动态显示图片的窗口并非难事,大概思路为:
1、 创建一个窗口。
2、 创一个内存DC,用存放要显示的图片。
3、 创建一个线程相隔一段时间将图片将绘制到屏幕DC上。
但是要将其封装在一个类中却并非一件容易的事情,为了以后方便使用我在这里封装一下。
介绍一下这个类的使用方法:
//定义一个窗口属性:
namespace AnimateWnd
{
struct Property
{
TSTRING strBkImage; //要显示图片的路径
RECT rcImagePosition; //要显示图片中区域
RECT rcDrawPosition; //窗口的位置
DWORD dwCount; //显示的帧数
DWORD dwTimeOut; //每帧的间隔时间
BOOL bVertical; // 图片是否为垂直的切割
};
}
//定义一个窗口对象
CAnimateWnd g_AnimateWnd;
//初始化窗口属性
AnimateWnd::Property pro;
RECT Drawrect = {80,27,401,200};
RECT Imagerect={0,0,1920,177};
pro.dwCount = 6;
pro.dwTimeOut = 300;
pro.rcDrawPosition = Drawrect;
pro.rcImagePosition = Imagerect;
pro.bVertical = FALSE;
pro.strBkImage = TEXT("//NAND//WinCeTemplate//1.bmp");
// 调用成员函数设置窗口属性
g_AnimateWnd.SetProperty(pro);
//调用成员函数创建窗口.其中hWnd是父窗口的句柄,如果没有父窗口的话直接设置为NULL
//TEXT("ANIMATE_CLS")为窗口类名,TEXT("ANIMATE_NAME")为窗口名.
g_AnimateWnd.Create(hWnd,TEXT("ANIMATE_CLS"),TEXT("ANIMATE_NAME"));
//调用成员函数显示窗口
g_AnimateWnd.ShowWindow(TRUE);
//调用成员函数动态显示图片
g_AnimateWnd.Start();
经过以上几步工作,我们的动态窗口显示的工作就完成了!
//Header.h
- #include<windows.h>
- #include<string>
- #ifdef UNICODE
- #ifndef TSTRING
- #define TSTRING std::wstring
- #endif
- #ifndef TSTRINGSTREAM
- #define TSTRINGSTREAM std::wstringstream
- #endif
- #else
- #ifndef TSTRING
- #define TSTRING std::string
- #endif
- #ifndef TSTRINGSTREAM
- #define TSTRINGSTREAM std::stringstream
- #endif
- #endif //#ifdef UNICODE
//WndBase.h
- // WndBase.h: interface for the CWndBase class.
- //
- //
- #pragma once
- #include "Header.h"
- class CWndBase
- {
- public:
- //----------------------------------------------------------------------
- //Description:
- // Show the window
- //----------------------------------------------------------------------
- virtual BOOL ShowWindow(BOOL bShow);
- //----------------------------------------------------------------------
- //Description:
- // Create the window
- //
- //Parameters:
- // hWndParent : [in] The parent window
- // strWndClass : [in] The class of the window
- // strWndName : [in] The name of the windows
- // bMsgThrdInside : [in] The message thread process is inside or not
- //----------------------------------------------------------------------
- virtual BOOL Create(HWND hWndParent,const TSTRING &strWndClass,const TSTRING &strWndName,BOOL bMsgThrdInside = FALSE);
- //----------------------------------------------------------------------
- //Description:
- // Create the window
- //
- //Parameters:
- // hWndParent : [in] The parent window
- // strWndClass : [in] The class of the window
- // strWndName : [in] The name of the windows
- // dwStyle : [in] The window type
- // bMsgThrdInside : [in] The message thread process is inside or not
- //----------------------------------------------------------------------
- virtual BOOL CreateEx(HWND hWndParent,const TSTRING &strWndClass,const TSTRING &strWndName,DWORD dwStyle,BOOL bMsgThrdInside = FALSE);
- //----------------------------------------------------------------------
- //Description:
- // Set the parent window
- //----------------------------------------------------------------------
- BOOL SetParentWindow(HWND hWndParent);
- //----------------------------------------------------------------------
- //Description:
- // Get the window handle
- //----------------------------------------------------------------------
- HWND GetWindow(void) const;
- //----------------------------------------------------------------------
- //Description:
- // Get the window parent
- //----------------------------------------------------------------------
- HWND GetParentWindow(void) const;
- public:
- CWndBase();
- virtual ~CWndBase();
- protected:
- //----------------------------------------------------------------------
- //Description:
- // Actual WndProc
- //----------------------------------------------------------------------
- virtual LRESULT WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
- //----------------------------------------------------------------------
- //Description:
- // Get the registry class data
- //Parameters:
- // wc : [out] The buffer for storing the data.
- //----------------------------------------------------------------------
- virtual void GetDataForRegistryClass(WNDCLASS &wc);
- private:
- //----------------------------------------------------------------------
- //Description:
- // Register window
- //----------------------------------------------------------------------
- BOOL RegisterClass();
- //----------------------------------------------------------------------
- //Description:
- // The process thread is for creating the window
- //----------------------------------------------------------------------
- static DWORD WINAPI CreateProc(PVOID pArg);
- //----------------------------------------------------------------------
- //Description:
- // Create the window
- //----------------------------------------------------------------------
- BOOL CreateWnd(DWORD dwStyle,DWORD dwExStyle);
- //----------------------------------------------------------------------
- //Description:
- // On Message WM_DESTROY
- //----------------------------------------------------------------------
- void OnDestroy(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
- //----------------------------------------------------------------------
- //Description:
- // Static WndProc wrapper and actual WndProc
- //----------------------------------------------------------------------
- static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
- private:
- BOOL m_bCreated;
- BOOL m_bMsgThrdInside;
- HANDLE m_hEventCreated;
- //The variable is for the common window use.
- HWND m_hWnd;
- mutable HWND m_hWndParent;
- TSTRING m_strWndClass;
- TSTRING m_strWndName;
- DWORD m_dwStyle;
- };
//WndBase.cpp
- #include "WndBase.h"
- //
- // Construction/Destruction
- //
- CWndBase::CWndBase():
- m_hWnd(NULL),
- m_hWndParent(NULL),
- m_bCreated(FALSE),
- m_hEventCreated(NULL),
- m_bMsgThrdInside(FALSE),
- m_dwStyle(WS_TABSTOP)
- {
- }
- CWndBase::~CWndBase()
- {
- }
- BOOL CWndBase::Create(HWND hWndParent,const TSTRING &strWndClass,const TSTRING &strWndName,BOOL bMsgThrdInside)
- {
- return CreateEx(hWndParent,strWndClass,strWndName,WS_TABSTOP ,bMsgThrdInside);
- }
- BOOL CWndBase::RegisterClass()
- {
- WNDCLASS wc;
- GetDataForRegistryClass(wc);
- return ::RegisterClass(&wc);
- }
- LRESULT CALLBACK CWndBase::StaticWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
- {
- CWndBase *pObject = reinterpret_cast<CWndBase*>(GetWindowLong(hWnd, GWL_USERDATA));
- if(pObject)
- {
- return pObject->WndProc(hWnd,wMsg,wParam,lParam);
- }
- else
- {
- return DefWindowProc(hWnd,wMsg,wParam,lParam);
- }
- }
- LRESULT CWndBase::WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
- {
- switch(wMsg)
- {
- case WM_DESTROY:
- OnDestroy(hWnd,wMsg,wParam,lParam);
- break;
- }
- return DefWindowProc(hWnd,wMsg,wParam,lParam);
- }
- BOOL CWndBase::ShowWindow(BOOL bShow)
- {
- if(m_hWnd == NULL)
- {
- return FALSE;
- }
- if(bShow == TRUE)
- {
- SetForegroundWindow(m_hWnd);
- SetWindowPos(m_hWnd,HWND_TOP,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
- }
- else
- {
- ::ShowWindow(m_hWnd,SW_HIDE);
- }
- return TRUE;
- }
- DWORD WINAPI CWndBase::CreateProc(PVOID pArg)
- {
- //Get the object instance
- CWndBase *pObject = reinterpret_cast<CWndBase *>(pArg);
- #ifdef _WIN32_WCE
- pObject->m_bCreated = pObject->CreateWnd(pObject->m_dwStyle,0);
- #else
- //Create the window.You should set the WS_EX_NOPARENTNOTIFY here, or maybe the CreateWindowEx
- //never return because it is waiting for the parent window responding when the main message loop doesn't begin working.
- pObject->m_bCreated = pObject->CreateWnd(pObject->m_dwStyle,WS_EX_NOPARENTNOTIFY);
- #endif //#ifdef _WIN32_WCE
- //Set the event
- if(pObject->m_hEventCreated != NULL)
- {
- SetEvent(pObject->m_hEventCreated);
- }
- if(pObject->m_bCreated == FALSE)
- {
- //Failed in creating the window, so return and needn't the message loop
- return 0x01;
- }
- //The message loop
- MSG msg;
- while(GetMessage(&msg,NULL,0,0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
- }
- BOOL CWndBase::CreateWnd(DWORD dwStyle,DWORD dwExStyle)
- {
- if(RegisterClass() == FALSE)
- {
- return FALSE;
- }
- RECT rcArea = {0};
- SystemParametersInfo(SPI_GETWORKAREA, 0, &rcArea, 0);
- m_hWnd = CreateWindowEx(dwExStyle,
- m_strWndClass.c_str(),
- m_strWndName.c_str(),
- dwStyle,
- rcArea.left,
- rcArea.top,
- rcArea.right - rcArea.left,
- rcArea.bottom - rcArea.top,
- m_hWndParent,
- NULL,
- GetModuleHandle(NULL),
- 0);
- ASSERT(m_hWnd != FALSE);
- if (IsWindow(m_hWnd) == FALSE)
- {
- return FALSE;
- }
- // If the window is created successfully, store this object so the
- //static wrapper can pass calls to the real WndProc.
- SetWindowLong(m_hWnd, GWL_USERDATA, reinterpret_cast<DWORD>(this));
- return TRUE;
- }
- void CWndBase::OnDestroy(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
- {
- if(m_bMsgThrdInside == TRUE)
- {
- //Exit the inside thread
- PostQuitMessage(0x00);
- }
- }
- HWND CWndBase::GetWindow(void) const
- {
- return m_hWnd;
- }
- HWND CWndBase::GetParentWindow(void) const
- {
- if(m_hWnd != NULL)
- {
- m_hWndParent = ::GetParent(m_hWnd);
- }
- return m_hWndParent;
- }
- BOOL CWndBase::SetParentWindow(HWND hWndParent)
- {
- if(m_hWnd == NULL)
- {
- m_hWndParent = hWndParent;
- return TRUE;
- }
- LONG lStyle = GetWindowLong(m_hWnd,GWL_STYLE);
- lStyle &= ~WS_POPUP; //Remove the WS_POPUP flag
- lStyle |= WS_CHILD; //Set the WS_CHILD flag
- SetWindowLong(m_hWnd,GWL_STYLE,lStyle);
- ::SetParent(m_hWnd,hWndParent);
- m_hWndParent = GetParentWindow();
- ASSERT(m_hWndParent != NULL);
- return (m_hWndParent != NULL);
- }
- BOOL CWndBase::CreateEx(HWND hWndParent,const TSTRING &strWndClass,const TSTRING &strWndName,DWORD dwStyle,BOOL bMsgThrdInside)
- {
- m_hWndParent = hWndParent;
- m_dwStyle = dwStyle;
- m_strWndName = strWndName;
- m_strWndClass = strWndClass;
- //Create the window
- if(bMsgThrdInside == TRUE)
- {
- HANDLE hdThrd = CreateThread(NULL,0,CreateProc,this,0,NULL);
- if(hdThrd == NULL )
- {
- return FALSE;
- }
- else
- {
- CloseHandle(hdThrd);
- //Create the event and wait
- m_hEventCreated = CreateEvent(NULL,FALSE,FALSE,NULL);
- if(m_hEventCreated != NULL)
- {
- WaitForSingleObject(m_hEventCreated,INFINITE);
- CloseHandle(m_hEventCreated);
- m_hEventCreated = NULL;
- return m_bCreated;
- }
- else
- {
- return FALSE;
- }
- }
- }
- else
- {
- return CreateWnd(dwStyle,0);
- }
- }
- void CWndBase::GetDataForRegistryClass(WNDCLASS &wc)
- {
- wc.style = 0;
- wc.lpfnWndProc = CWndBase::StaticWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = GetModuleHandle(NULL);
- wc.hIcon = NULL;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = m_strWndClass.c_str();
- wc.hbrBackground = NULL;//If you don't set NULL,it would erase the background when showing that causes flash.
- }
- #pragma once
- #include"Header.h"
- #include <vector>
- #include <map>
- namespace EventThread
- {
- enum Flag
- {
- FLAG_ASYNC,
- FLAG_SYNC,
- };
- };
- class CEventThread
- {
- public:
- //------------------------------------------
- //Description:
- // Create the thread.After succeeding in creating,you should
- //call Close to release resource.
- //
- //Parameters:
- // vtEventName : [in] The event to trigger.
- //------------------------------------------
- BOOL Create(const std::vector<TSTRING> &vtEventName);
- //-----------------------------------------------------------------------------------------------------------------
- //Description:
- // Start the thread to run.
- //Parameters:
- // dwTimeout : [in] The timeout for the waiting.
- // flag : [in] FLAG_ASYNC -- The function would return immediately after notify the thread to start, which means
- // when the function return the thread may not be running yet.
- // FLAG_SYNC -- It wouldn't return when the thread running.
- //-------------------------------------------------------------------------------------------------------------------
- BOOL Start(DWORD dwTimeout,EventThread::Flag flag = EventThread::FLAG_SYNC);
- //-----------------------------------------------------------------------------------------------------------------------
- //Description:
- // Stop the thread running.
- //Parameters:
- // flag : [in] FLAG_ASYNC -- The function would return immediately after notify the thread to exit, which means
- // when the function return the thread would still running. You could call IsRunning to check
- // whether the thread really exit.
- // FLAG_SYNC -- It wouldn't return when the thread doesn't running. You couldn't set the parameters
- // as the value in the callback function,or it would call dead locked!!
- //
- //------------------------------------------------------------------------------------------------------------------------
- BOOL Stop(EventThread::Flag flag = EventThread::FLAG_ASYNC);
- //-----------------------------------------------------------------------------------------------
- //Description:
- // Close the thread.
- //Parameters:
- // flag : [in] FLAG_ASYNC -- The function would return immediately after notify the thread to exit, which means
- // when the function return the thread would still running. You could call IsRunning to check
- // whether the thread really exit.
- // FLAG_SYNC -- It wouldn't return when the thread doesn't running. You couldn't set the parameters
- // as the value in the callback function,or it would call dead locked!!
- //
- //-----------------------------------------------------------------------------------------------
- void Close(EventThread::Flag flag);
- //--------------------------------------------------------------------------------------------------------------
- //Description:
- // If the monitor thread doesn't exit,it return TRUE. Be careful,if you succeed in calling Stop but not Close,the
- //function also return TRUE,because the Stop doesn't cause the monitor process to exit.If you want to check
- //whether the process is stop or not,you should call IsStop.
- //--------------------------------------------------------------------------------------------------------------
- BOOL IsRunning();
- //-------------------------------------------------------------------------------------------------------
- //Description:
- // Check the thread whether stop monitoring event or not. If return TRUE,the function which set by SetHandleEventFunc
- //or SetHandleTimeoutFunc never be called.
- //-------------------------------------------------------------------------------------------------------
- BOOL IsStop();
- //----------------------------------------------------------------
- //Description:
- // Set the callback funtion for the handle event
- //Parameters:
- // pHandleEventFunc : [in] The callback function address
- // pParam : [in] The parameter pass to the callback function when calling
- //---------------------------------------------------------------
- typedef void (*HANDLE_EVENT_FUNC)(const TSTRING& strEventName,DWORD dwEventData,PVOID pParam);
- void SetHandleEventFunc(HANDLE_EVENT_FUNC pHandleEventFunc,PVOID pParam);
- //----------------------------------------------------------------
- //Description:
- // Set the callback funtion for the handle timeout
- //Parameters:
- // pHandleTimeoutFunc : [in] The callback function address
- // pParam : [in] The parameter pass to the callback function when calling
- //---------------------------------------------------------------
- typedef void (*HANDLE_TIMEOUT_FUNC)(PVOID pParam);
- void SetHandleTimeoutFunc(HANDLE_TIMEOUT_FUNC pHandleTimeoutFunc,PVOID pParam);
- //----------------------------------------------------------------
- //Description:
- // This function sets the priority value for the specified thread.
- //Parameters:
- // iPriority : [in] Specifies the priority value for the thread.
- // You should set the value as follows:
- // THREAD_PRIORITY_TIME_CRITICAL
- // THREAD_PRIORITY_HIGHEST
- // THREAD_PRIORITY_ABOVE_NORMAL
- // THREAD_PRIORITY_NORMAL
- // THREAD_PRIORITY_BELOW_NORMAL
- // THREAD_PRIORITY_LOWEST
- // THREAD_PRIORITY_ABOVE_IDLE
- // THREAD_PRIORITY_IDLE
- //----------------------------------------------------------------
- void SetPriority(int iPriority);
- //----------------------------------------------------------------
- //Description:
- // This function get the priority value.
- //----------------------------------------------------------------
- int GetPriority();
- //----------------------------------------------------------------
- //Description:
- // This function set the timeout for the event
- //Parameters:
- // dwTimeout : [in] The timeout to set
- //----------------------------------------------------------------
- void SetTimeout(DWORD dwTimeout);
- //----------------------------------------------------------------
- //Description:
- // This function Get the timeout for the event
- //----------------------------------------------------------------
- DWORD GetTimeout();
- public:
- CEventThread();
- virtual ~CEventThread();
- protected:
- //---------------------------------------------------------------------
- //Description:
- // Handle the event.It's for the derived class used
- //Parameters:
- // strEventName : [in] The event name
- // dwEventData : [in] The event data
- //----------------------------------------------------------------------
- virtual void HandleEvent(const TSTRING& strEventName,DWORD dwEventData) {};
- //----------------------------------------------------------------------
- //Description:
- // Handle the timeout.It's for the derived class used
- //----------------------------------------------------------------------
- virtual void HandleTimeout() {};
- //----------------------------------------------------------------------
- //Description:
- // Reset all the event
- //----------------------------------------------------------------------
- void ResetAllEvent();
- private:
- //---------------------------------------------------------------------------
- //Description:
- // Add the event
- //Parameters:
- // strEventName : [in] The event name to add
- //---------------------------------------------------------------------------
- void AddEvent(const TSTRING &strEventName);
- //---------------------------------------------------------------------------
- //Description:
- // The process for monitor the event
- //---------------------------------------------------------------------------
- static DWORD WINAPI MonitorProc(PVOID pParam);
- //---------------------------------------------------------------------------
- //Description:
- // Release the resource
- //---------------------------------------------------------------------------
- void ReleaserResource();
- private:
- std::vector<HANDLE> m_vtEvent;
- std::map<DWORD,TSTRING> m_mpEventIndex;
- HANDLE m_hEventAwake;
- BOOL m_bCreated;
- BOOL m_bProcRunning;
- BOOL m_bStop;
- DWORD m_dwTimeout;
- int m_iPriority;
- HANDLE m_hThrd;
- struct HandleEventFuncData
- {
- HANDLE_EVENT_FUNC pHandleEventFunc;
- PVOID pParam;
- };
- HandleEventFuncData m_HandleEventFuncData;
- struct HandleTimeoutFuncData
- {
- HANDLE_TIMEOUT_FUNC pHandleTimeoutFunc;
- PVOID pParam;
- };
- HandleTimeoutFuncData m_HandleTimeoutFuncData;
- enum AwakeData
- {
- AWD_NONE,
- AWD_EXIT,
- AWD_RESTART,
- AWD_STOP,
- };
- AwakeData m_AwakeData;
- };
//EventThread.cpp
- #include "EventThread.h"
- #include <algorithm>
- #ifdef _WIN32_WCE
- #include "Pkfuncs.h"
- #endif //#ifndef _WIN32_WCE
- CEventThread::CEventThread():
- m_hEventAwake(NULL),
- m_bCreated(FALSE),
- m_dwTimeout(0),
- m_bProcRunning(FALSE),
- m_AwakeData(AWD_NONE),
- m_iPriority(THREAD_PRIORITY_NORMAL),
- m_hThrd(NULL),
- m_bStop(TRUE)
- {
- memset(&m_HandleEventFuncData,0,sizeof(m_HandleEventFuncData));
- memset(&m_HandleTimeoutFuncData,0,sizeof(m_HandleTimeoutFuncData));
- }
- CEventThread::~CEventThread()
- {
- }
- BOOL CEventThread::Create(const std::vector<TSTRING> &vtEventName)
- {
- BOOL bRes = FALSE;
- if(m_bCreated != FALSE)
- {
- return FALSE;
- }
- for(std::vector<TSTRING>::const_iterator iter = vtEventName.begin(); iter != vtEventName.end(); iter ++)
- {
- AddEvent(*iter);
- }
- //The event for awake only
- m_hEventAwake = CreateEvent(NULL,TRUE,FALSE,NULL);
- m_vtEvent.push_back(m_hEventAwake);
- m_mpEventIndex.insert(std::make_pair(m_mpEventIndex.size(),TEXT("")));
- m_bCreated = TRUE;
- return TRUE;
- }
- void CEventThread::Close(EventThread::Flag flag)
- {
- if(m_bProcRunning != FALSE)
- {
- InterlockedExchange(reinterpret_cast<LONG *>(&m_AwakeData),AWD_EXIT);
- SetEvent(m_hEventAwake);
- if(flag == EventThread::FLAG_ASYNC)
- {
- return;
- }
- //Wait untill the process exit
- while(InterlockedExchange(reinterpret_cast<LONG *>(&m_bProcRunning),TRUE) == TRUE)
- {
- SetEvent(m_hEventAwake);
- Sleep(100);
- }
- InterlockedExchange(reinterpret_cast<LONG *>(&m_bProcRunning),FALSE);
- }
- CloseHandle(m_hThrd);
- m_hThrd = NULL;
- }
- BOOL CEventThread::Start(DWORD dwTimeout,EventThread::Flag flag)
- {
- m_dwTimeout = dwTimeout;
- if(m_bProcRunning == FALSE)
- {
- InterlockedExchange(reinterpret_cast<LONG *>(&m_AwakeData),AWD_NONE);
- if(m_hThrd != NULL)
- {
- CloseHandle(m_hThrd);
- m_hThrd = NULL;
- }
- m_hThrd = CreateThread(NULL,NULL,MonitorProc,this,NULL,NULL);
- SetThreadPriority(m_hThrd,m_iPriority);
- if(flag == EventThread::FLAG_SYNC)
- {
- //Wait untill the thread process funtion running.
- while(InterlockedExchange(reinterpret_cast<LONG *>(&m_bProcRunning),FALSE) == FALSE)
- {
- Sleep(100);
- }
- InterlockedExchange(reinterpret_cast<LONG *>(&m_bProcRunning),TRUE);
- }
- }
- else
- {
- InterlockedExchange(reinterpret_cast<LONG *>(&m_AwakeData),AWD_RESTART);
- }
- SetEvent(m_hEventAwake);
- return TRUE;
- }
- BOOL CEventThread::Stop(EventThread::Flag flag)
- {
- InterlockedExchange(reinterpret_cast<LONG *>(&m_AwakeData),AWD_STOP);
- SetEvent(m_hEventAwake);
- if(flag == EventThread::FLAG_SYNC)
- {
- //Wait untill the flag set TRUE
- while(InterlockedExchange(reinterpret_cast<LONG *>(&m_bStop),FALSE) == FALSE)
- {
- InterlockedExchange(reinterpret_cast<LONG *>(&m_AwakeData),AWD_STOP);
- SetEvent(m_hEventAwake);
- Sleep(100);
- }
- InterlockedExchange(reinterpret_cast<LONG *>(&m_bStop),TRUE);
- }
- return TRUE;
- }
- void CEventThread::AddEvent(const TSTRING &strEventName)
- {
- HANDLE hEvent = CreateEvent(NULL,TRUE,FALSE,strEventName.c_str());
- m_vtEvent.push_back(hEvent);
- m_mpEventIndex.insert(std::make_pair(m_vtEvent.size() - 1,strEventName.c_str()));
- ResetEvent(hEvent);
- }
- DWORD WINAPI CEventThread::MonitorProc(PVOID pParam)
- {
- CEventThread *pObj = reinterpret_cast<CEventThread *>(pParam);
- if(pObj == NULL)
- {
- return 0x10;
- }
- if(InterlockedExchange(reinterpret_cast<LONG *>(&pObj->m_bProcRunning),TRUE) != FALSE)
- {
- //Another thread is running, so exit.
- return 0x20;
- }
- while(TRUE)
- {
- BOOL bStop = FALSE;
- //Set the timeout for the waiting
- DWORD dwTimeout = 0;
- if(pObj->m_AwakeData == AWD_STOP)
- {
- dwTimeout = INFINITE;
- InterlockedExchange(reinterpret_cast<LONG *>(&pObj->m_bStop),TRUE);
- bStop = TRUE;
- }
- else
- {
- dwTimeout = pObj->m_dwTimeout;
- InterlockedExchange(reinterpret_cast<LONG *>(&pObj->m_bStop),FALSE);
- }
- if(pObj->m_AwakeData == AWD_EXIT)
- {
- //Exit the process
- break;
- }
- //Reset the flag
- InterlockedExchange(reinterpret_cast<LONG *>(&pObj->m_AwakeData),AWD_NONE);
- //Wait for the event
- DWORD dwObj = 0;
- if(bStop != FALSE)
- {
- //May be the awake event send by the call backfunction,so I need reset it here
- ResetEvent(pObj->m_hEventAwake);
- dwObj = WaitForSingleObject(pObj->m_hEventAwake,dwTimeout);
- }
- else
- {
- dwObj = WaitForMultipleObjects(pObj->m_vtEvent.size(),&pObj->m_vtEvent[0],FALSE,dwTimeout);
- }
- if(WAIT_TIMEOUT != dwObj)
- {
- if(pObj->m_AwakeData == AWD_EXIT)
- {
- //Exit the process
- break;
- }
- if(pObj->m_AwakeData == AWD_RESTART || pObj->m_AwakeData == AWD_STOP)
- {
- ResetEvent(pObj->m_hEventAwake);
- //Go to the next waitin
- continue;
- }
- }
- else
- {
- pObj->HandleTimeout();
- if(pObj->m_HandleTimeoutFuncData.pHandleTimeoutFunc != NULL)
- {
- pObj->m_HandleTimeoutFuncData.pHandleTimeoutFunc(pObj->m_HandleTimeoutFuncData.pParam);
- }
- continue;
- }
- //Because I am afraid that other application notify the event by SetEvent,so I reset the event here.
- ResetEvent(pObj->m_vtEvent[dwObj - WAIT_OBJECT_0]);
- DWORD dwIndex = dwObj - WAIT_OBJECT_0;
- if(dwIndex == pObj->m_vtEvent.size() - 1)
- {
- //It's the awake event,needn't do anything
- continue;
- }
- //Handle the event
- std::map<DWORD,TSTRING>::iterator iter = pObj->m_mpEventIndex.find(dwObj - WAIT_OBJECT_0);
- if(iter != pObj->m_mpEventIndex.end())
- {
- pObj->HandleEvent(iter->second,GetEventData(pObj->m_vtEvent[dwObj - WAIT_OBJECT_0]));
- if(pObj->m_HandleEventFuncData.pHandleEventFunc != NULL)
- {
- pObj->m_HandleEventFuncData.pHandleEventFunc(iter->second,GetEventData(pObj->m_vtEvent[dwObj - WAIT_OBJECT_0]),pObj->m_HandleEventFuncData.pParam);
- }
- }
- }
- pObj->ReleaserResource();
- InterlockedExchange(reinterpret_cast<LONG *>(&pObj->m_bProcRunning),FALSE);
- return 0;
- }
- void CEventThread::SetHandleEventFunc(HANDLE_EVENT_FUNC pHandleEventFunc,PVOID pParam)
- {
- m_HandleEventFuncData.pHandleEventFunc = pHandleEventFunc;
- m_HandleEventFuncData.pParam = pParam;
- }
- void CEventThread::SetHandleTimeoutFunc(HANDLE_TIMEOUT_FUNC pHandleTimeoutFunc,PVOID pParam)
- {
- m_HandleTimeoutFuncData.pHandleTimeoutFunc = pHandleTimeoutFunc;
- m_HandleTimeoutFuncData.pParam = pParam;
- }
- BOOL CEventThread::IsRunning()
- {
- return m_bProcRunning;
- }
- void CEventThread::ReleaserResource()
- {
- //Close the event
- std::for_each(m_vtEvent.begin(),m_vtEvent.end(),std::ptr_fun(CloseHandle));
- m_vtEvent.swap(std::vector<HANDLE>());
- m_mpEventIndex.clear();
- m_hEventAwake = NULL;
- m_bCreated = FALSE;
- }
- void CEventThread::SetPriority(int iPriority)
- {
- m_iPriority = iPriority;
- if(m_hThrd != NULL)
- {
- SetThreadPriority(m_hThrd,m_iPriority);
- }
- }
- void CEventThread::SetTimeout(DWORD dwTimeout)
- {
- m_dwTimeout = dwTimeout;
- InterlockedExchange(reinterpret_cast<LONG *>(&m_AwakeData),AWD_RESTART);
- SetEvent(m_hEventAwake);
- }
- DWORD CEventThread::GetTimeout()
- {
- return m_dwTimeout;
- }
- int CEventThread::GetPriority()
- {
- return m_iPriority;
- }
- void CEventThread::ResetAllEvent()
- {
- for(std::vector<HANDLE>::iterator iter = m_vtEvent.begin(); iter != m_vtEvent.end(); iter ++)
- {
- ResetEvent(*iter);
- }
- }
- BOOL CEventThread::IsStop()
- {
- return m_bStop;
- }
//AnimateWnd.h
- #include "WndBase.h"
- #include "MemDC.h"
- #include "EventThread.h"
- namespace AnimateWnd
- {
- struct Property
- {
- TSTRING strBkImage;
- RECT rcImagePosition;
- RECT rcDrawPosition;
- DWORD dwCount;
- DWORD dwTimeOut;
- BOOL bVertical;
- };
- }
- class CAnimateWnd:
- public CWndBase
- {
- public:
- //----------------------------------------------------------------------
- //Description:
- // Create the window
- //
- //Parameters:
- // hWndParent : [in] The parent window
- // strWndClass : [in] The class of the window
- // strWndName : [in] The name of the windows
- // bMsgThrdInside : [in] The message thread process is inside or not
- //----------------------------------------------------------------------
- virtual BOOL Create(HWND hWndParent,const TSTRING &strWndClass,const TSTRING &strWndName,BOOL bMsgThrdInside = FALSE);
- //--------------------------------------------------------------------
- //Description:
- // Set all the property for the AnimateWnd
- //---------------------------------------------------------------------
- BOOL SetProperty(const AnimateWnd::Property &Property);
- //--------------------------------------------------------------------
- //Description:
- // Set all the property for the AnimateWnd
- //---------------------------------------------------------------------
- BOOL GetProPerty(AnimateWnd::Property &Property);
- //--------------------------------------------------------------------
- //Description:
- // Start Play animateWnd
- //---------------------------------------------------------------------
- void Start();
- //--------------------------------------------------------------------
- //Description:
- // Start Play animateWnd
- //---------------------------------------------------------------------
- void Stop();
- public:
- CAnimateWnd();
- virtual ~CAnimateWnd();
- protected:
- //----------------------------------------------------------------------
- //Description:
- // You should see the description in the base class
- //----------------------------------------------------------------------
- virtual LRESULT WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
- //----------------------------------------------------------------------
- //Description:
- // Draw image to hdc
- //----------------------------------------------------------------------
- void DrawWnd();
- //Draw image to m_MemImge
- void DrawMemDC();
- //----------------------------------------------------------------------
- //Description:
- // Refresh Thread
- //----------------------------------------------------------------------
- static void RefreshProc(LPVOID pArg);
- private:
- AnimateWnd::Property m_Property;
- CMemDC m_MemImge;
- DWORD m_dwIndex;
- CEventThread m_EventRefreshThrd;
- };
//AnimateWnd.cpp
- #include "AnimateWnd.h"
- CAnimateWnd::CAnimateWnd():
- m_dwIndex(0)
- {
- std::vector<TSTRING> vtEvent;
- m_EventRefreshThrd.Create(vtEvent);
- m_EventRefreshThrd.SetHandleTimeoutFunc(RefreshProc,this);
- }
- CAnimateWnd::~CAnimateWnd()
- {
- if(m_MemImge.IsOK())
- {
- m_MemImge.Delete();
- }
- m_EventRefreshThrd.Close(EventThread::FLAG_SYNC);
- }
- BOOL CAnimateWnd::Create(HWND hWndParent,const TSTRING &strWndClass,const TSTRING &strWndName,BOOL bMsgThrdInside)
- {
- BOOL bReturn = CWndBase::CreateEx(hWndParent,strWndClass,strWndName,WS_TABSTOP,bMsgThrdInside);
- if(bReturn)
- {
- RECT rcParent ={0};
- ::GetWindowRect(hWndParent,&rcParent);
- ::MoveWindow(GetWindow(),
- m_Property.rcDrawPosition.left + rcParent.left,
- m_Property.rcDrawPosition.top + rcParent.top,
- m_Property.rcDrawPosition.right - m_Property.rcDrawPosition.left,
- m_Property.rcDrawPosition.bottom- m_Property.rcDrawPosition.top,
- TRUE);
- }
- return bReturn;
- }
- LRESULT CAnimateWnd::WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
- {
- switch(wMsg)
- {
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- HDC hdc;
- hdc = BeginPaint(hWnd,&ps);
- DrawWnd();
- EndPaint(hWnd,&ps);
- return 0;
- }
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hWnd,wMsg,wParam,lParam);
- }
- void CAnimateWnd::Start()
- {
- m_EventRefreshThrd.Start(m_Property.dwTimeOut);
- }
- void CAnimateWnd::Stop()
- {
- m_EventRefreshThrd.Stop();
- }
- void CAnimateWnd::RefreshProc(LPVOID pArg)
- {
- CAnimateWnd *pObj= reinterpret_cast<CAnimateWnd *>(pArg);
- //只有在父窗口和自身窗口可见的时候才需要刷新
- if( ::IsWindowVisible(pObj->GetParentWindow()) && ::IsWindowVisible(pObj->GetWindow()))
- {
- pObj->DrawWnd();
- pObj->m_dwIndex++;
- if(pObj->m_dwIndex >= pObj->m_Property.dwCount )
- {
- pObj->m_dwIndex = 0;
- }
- }
- }
- BOOL CAnimateWnd::SetProperty(const AnimateWnd::Property &Property)
- {
- m_Property.dwCount = Property.dwCount;
- m_Property.dwTimeOut = Property.dwTimeOut;
- m_Property.rcDrawPosition = Property.rcDrawPosition;
- m_Property.rcImagePosition= Property.rcImagePosition;
- m_Property.strBkImage = Property.strBkImage;
- m_Property.bVertical = Property.bVertical;
- DrawMemDC();
- return TRUE;
- }
- BOOL CAnimateWnd::GetProPerty(AnimateWnd::Property &Property)
- {
- Property.dwCount = m_Property.dwCount;
- Property.dwTimeOut = m_Property.dwTimeOut;
- Property.rcDrawPosition = m_Property.rcDrawPosition;
- Property.rcImagePosition= m_Property.rcImagePosition;
- Property.strBkImage = m_Property.strBkImage;
- Property.bVertical = m_Property.bVertical;
- return TRUE;
- }
- void CAnimateWnd::DrawWnd()
- {
- if(!m_MemImge.IsOK())
- {
- DrawMemDC();
- }
- HDC hdc = GetDC(GetWindow());
- HBITMAP hBmp = SHLoadDIBitmap(m_Property.strBkImage.c_str());
- if(m_Property.bVertical == TRUE)
- {
- int iHeight = m_MemImge.GetHeight()/ m_Property.dwCount;
- StretchBlt( hdc,
- 0,
- 0,
- m_Property.rcDrawPosition.right - m_Property.rcDrawPosition.left,
- m_Property.rcDrawPosition.bottom - m_Property.rcDrawPosition.top,
- m_MemImge.GetDC(),
- 0,
- iHeight * m_dwIndex,
- m_MemImge.GetWidth(),
- iHeight,
- SRCCOPY
- );
- }
- else
- {
- int iWidth = m_MemImge.GetWidth() / m_Property.dwCount;
- RECT rc;
- GetClientRect(GetWindow(),&rc);
- StretchBlt( hdc,
- 0,
- 0,
- m_Property.rcDrawPosition.right - m_Property.rcDrawPosition.left,
- m_Property.rcDrawPosition.bottom - m_Property.rcDrawPosition.top,
- m_MemImge.GetDC(),
- iWidth * m_dwIndex,
- 0,
- iWidth,
- m_MemImge.GetHeight(),
- SRCCOPY
- );
- }
- ReleaseDC(GetWindow(),hdc);
- }
- void CAnimateWnd::DrawMemDC()
- {
- if(m_MemImge.IsOK())
- {
- m_MemImge.Delete();
- }
- HDC hdc = GetDC(GetWindow());
- SIZE size ={m_Property.rcImagePosition.right - m_Property.rcImagePosition.left,m_Property.rcImagePosition.bottom - m_Property.rcImagePosition.top};
- m_MemImge.Create(hdc,&size);
- ReleaseDC(GetWindow(),hdc);
- #ifdef _WIN32_WCE
- HBITMAP hBmp = SHLoadDIBitmap(m_Property.strBkImage.c_str());
- #else
- HBITMAP hBmp = reinterpret_cast<HBITMAP>(LoadImage(NULL,m_Property.strBkImage.c_str(),IMAGE_BITMAP,0,0,LR_LOADFROMFILE));
- #endif
- if(hBmp == NULL)
- {
- return ;
- }
- //Crete the bitmap DC
- HDC hdcBmp = CreateCompatibleDC(m_MemImge.GetDC());
- HGDIOBJ hOldSel = SelectObject(hdcBmp,hBmp);
- StretchBlt(
- m_MemImge.GetDC(),
- 0,
- 0,
- m_MemImge.GetWidth(),
- m_MemImge.GetHeight(),
- hdcBmp,
- m_Property.rcImagePosition.left,
- m_Property.rcImagePosition.top,
- size.cx,
- size.cy,
- SRCCOPY
- );
- //Delete the bitmap DC
- SelectObject(hdcBmp,hOldSel);
- DeleteDC(hdcBmp);
- //Delete the bmp
- DeleteObject(hBmp);
- }
其中代码中CMemDC类的实现在http://blog.csdn.net/lanyzh0909/archive/2010/08/07/5795590.aspx有实现代码.
测试代码:
- #include"AnimateWnd.h"
- CAnimateWnd g_AnimateWnd;
- int WINAPI WinMain( HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPTSTR lpCmdLine,
- int nCmdShow)
- {
- MSG msg;
- CWndBase MainWnd;
- MainWnd.Create(NULL,TEXT("MAIN_CLS"),TEXT("窗口显示"));
- MainWnd.ShowWindow(TRUE);
- //初始化窗口属性
- AnimateWnd::Property pro;
- RECT Drawrect = {80,27,401,200};
- RECT Imagerect={0,0,1920,177};
- pro.dwCount = 6;
- pro.dwTimeOut = 300;
- pro.rcDrawPosition = Drawrect;
- pro.rcImagePosition = Imagerect;
- pro.bVertical = FALSE;
- pro.strBkImage = TEXT("//NAND//WinCeTemplate//1.bmp");
- // 调用成员函数设置窗口属性
- g_AnimateWnd.SetProperty(pro);
- //调用成员函数创建窗口,其中hWnd是父窗口的句柄,如果没有父窗口的话直接设置为NULL
- g_AnimateWnd.Create(MainWnd.GetWindow(),TEXT("ANIMATE_CLS"),TEXT("ANIMATE_NAME"));
- //调用成员函数显示窗口
- g_AnimateWnd.ShowWindow(TRUE);
- //调用成员函数动态显示图片
- g_AnimateWnd.Start();
- while(GetMessage(&msg,NULL,0,0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
- }
//EventThread.h