📄 atlapp.h
字号:
{
::WaitForSingleObject(m_hEventShutdown, INFINITE);
DWORD dwWait = 0;
do
{
m_bActivity = false;
dwWait = ::WaitForSingleObject(m_hEventShutdown, m_dwTimeOut);
}
while(dwWait == WAIT_OBJECT_0);
// timed out
if(!m_bActivity && m_nLockCnt == 0) // if no activity let's really bail
{
#if ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) & defined(_ATL_FREE_THREADED)
::CoSuspendClassObjects();
if(!m_bActivity && m_nLockCnt == 0)
#endif
break;
}
}
// This handle should be valid now. If it isn't,
// check if _Module.Term was called first (it shouldn't)
if(::CloseHandle(m_hEventShutdown))
m_hEventShutdown = NULL;
::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0);
}
bool StartMonitor()
{
m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL);
if(m_hEventShutdown == NULL)
return false;
DWORD dwThreadID;
#if !defined(_ATL_MIN_CRT) & defined(_MT)
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))MonitorProc, this, 0, (UINT*)&dwThreadID);
#else
HANDLE hThread = ::CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
#endif
bool bRet = (hThread != NULL);
if(bRet)
::CloseHandle(hThread);
return bRet;
}
static DWORD WINAPI MonitorProc(void* pv)
{
CServerAppModule* p = (CServerAppModule*)pv;
p->MonitorShutdown();
#if !defined(_ATL_MIN_CRT) & defined(_MT)
_endthreadex(0);
#endif
return 0;
}
// Scan command line and perform registration
// Return value specifies if server should run
// Parses the command line and registers/unregisters the rgs file if necessary
bool ParseCommandLine(LPCTSTR lpCmdLine, UINT nResId, HRESULT* pnRetCode)
{
TCHAR szTokens[] = _T("-/");
*pnRetCode = S_OK;
LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
while(lpszToken != NULL)
{
if(lstrcmpi(lpszToken, _T("UnregServer"))==0)
{
*pnRetCode = UnregisterServer(TRUE);
ATLASSERT(SUCCEEDED(*pnRetCode));
if(FAILED(*pnRetCode))
return false;
*pnRetCode = UpdateRegistryFromResource(nResId, FALSE);
return false;
}
// Register as Local Server
if(lstrcmpi(lpszToken, _T("RegServer"))==0)
{
*pnRetCode = UpdateRegistryFromResource(nResId, TRUE);
ATLASSERT(SUCCEEDED(*pnRetCode));
if(FAILED(*pnRetCode))
return false;
*pnRetCode = RegisterServer(TRUE);
return false;
}
lpszToken = FindOneOf(lpszToken, szTokens);
}
return true;
}
// Parses the command line and registers/unregisters the appid if necessary
bool ParseCommandLine(LPCTSTR lpCmdLine, LPCTSTR pAppId, HRESULT* pnRetCode)
{
TCHAR szTokens[] = _T("-/");
*pnRetCode = S_OK;
LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
while(lpszToken != NULL)
{
if(lstrcmpi(lpszToken, _T("UnregServer"))==0)
{
*pnRetCode = UnregisterAppId(pAppId);
ATLASSERT(SUCCEEDED(*pnRetCode));
if(FAILED(*pnRetCode))
return false;
*pnRetCode = UnregisterServer(TRUE);
return false;
}
// Register as Local Server
if(lstrcmpi(lpszToken, _T("RegServer"))==0)
{
*pnRetCode = RegisterAppId(pAppId);
ATLASSERT(SUCCEEDED(*pnRetCode));
if(FAILED(*pnRetCode))
return false;
*pnRetCode = RegisterServer(TRUE);
return false;
}
lpszToken = FindOneOf(lpszToken, szTokens);
}
return true;
}
#if (_ATL_VER < 0x0700)
// search for an occurence of string p2 in string p1
static LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
{
while(p1 != NULL && *p1 != NULL)
{
LPCTSTR p = p2;
while(p != NULL && *p != NULL)
{
if(*p1 == *p)
return ::CharNext(p1);
p = ::CharNext(p);
}
p1 = ::CharNext(p1);
}
return NULL;
}
HRESULT RegisterAppId(LPCTSTR pAppId)
{
CRegKey keyAppID;
if(keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_READ) == ERROR_SUCCESS)
{
TCHAR szModule1[_MAX_PATH];
TCHAR szModule2[_MAX_PATH];
TCHAR* pszFileName;
::GetModuleFileName(GetModuleInstance(), szModule1, _MAX_PATH);
::GetFullPathName(szModule1, _MAX_PATH, szModule2, &pszFileName);
CRegKey keyAppIDEXE;
if(keyAppIDEXE.Create(keyAppID, pszFileName, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE) == ERROR_SUCCESS)
keyAppIDEXE.SetValue(pAppId, _T("AppID"));
if(keyAppIDEXE.Create(keyAppID, pAppId, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE) == ERROR_SUCCESS)
keyAppIDEXE.SetValue(pszFileName);
}
return S_OK;
}
HRESULT UnregisterAppId(LPCTSTR pAppId)
{
CRegKey keyAppID;
if(keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_READ) == ERROR_SUCCESS)
{
TCHAR szModule1[_MAX_PATH];
TCHAR szModule2[_MAX_PATH];
TCHAR* pszFileName;
::GetModuleFileName(GetModuleInstance(), szModule1, _MAX_PATH);
::GetFullPathName(szModule1, _MAX_PATH, szModule2, &pszFileName);
keyAppID.RecurseDeleteKey(pszFileName);
keyAppID.RecurseDeleteKey(pAppId);
}
return S_OK;
}
#endif //(_ATL_VER < 0x0700)
};
/////////////////////////////////////////////////////////////////////////////
// ATL 3.0 Add-ons
// protect template members from windowsx.h macros
#ifdef _INC_WINDOWSX
#undef SubclassWindow
#endif //_INC_WINDOWSX
// define useful macros from windowsx.h
#ifndef GET_X_LPARAM
#define GET_X_LPARAM(lParam) ((int)(short)LOWORD(lParam))
#endif
#ifndef GET_Y_LPARAM
#define GET_Y_LPARAM(lParam) ((int)(short)HIWORD(lParam))
#endif
/////////////////////////////////////////////////////////////////////////////
// Dual argument helper classes
#ifndef _WTL_NO_UNION_CLASSES
class _U_RECT
{
public:
_U_RECT(LPRECT lpRect) : m_lpRect(lpRect)
{ }
_U_RECT(RECT& rc) : m_lpRect(&rc)
{ }
LPRECT m_lpRect;
};
class _U_MENUorID
{
public:
_U_MENUorID(HMENU hMenu) : m_hMenu(hMenu)
{ }
_U_MENUorID(UINT nID) : m_hMenu((HMENU)LongToHandle(nID))
{ }
HMENU m_hMenu;
};
class _U_STRINGorID
{
public:
_U_STRINGorID(LPCTSTR lpString) : m_lpstr(lpString)
{ }
_U_STRINGorID(UINT nID) : m_lpstr(MAKEINTRESOURCE(nID))
{ }
LPCTSTR m_lpstr;
};
#endif //!_WTL_NO_UNION_CLASSES
/////////////////////////////////////////////////////////////////////////////
// Forward notifications support for message maps
#if (_ATL_VER < 0x0700)
// forward notifications support
#define FORWARD_NOTIFICATIONS() \
{ \
bHandled = TRUE; \
lResult = Atl3ForwardNotifications(m_hWnd, uMsg, wParam, lParam, bHandled); \
if(bHandled) \
return TRUE; \
}
static LRESULT Atl3ForwardNotifications(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
LRESULT lResult = 0;
switch(uMsg)
{
case WM_COMMAND:
case WM_NOTIFY:
case WM_PARENTNOTIFY:
case WM_DRAWITEM:
case WM_MEASUREITEM:
case WM_COMPAREITEM:
case WM_DELETEITEM:
case WM_VKEYTOITEM:
case WM_CHARTOITEM:
case WM_HSCROLL:
case WM_VSCROLL:
case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLORSCROLLBAR:
case WM_CTLCOLORSTATIC:
lResult = ::SendMessage(::GetParent(hWnd), uMsg, wParam, lParam);
break;
default:
bHandled = FALSE;
break;
}
return lResult;
}
/////////////////////////////////////////////////////////////////////////////
// Reflected message handler macros for message maps
#define REFLECTED_COMMAND_HANDLER(id, code, func) \
if(uMsg == OCM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \
{ \
bHandled = TRUE; \
lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
if(bHandled) \
return TRUE; \
}
#define REFLECTED_COMMAND_ID_HANDLER(id, func) \
if(uMsg == OCM_COMMAND && id == LOWORD(wParam)) \
{ \
bHandled = TRUE; \
lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
if(bHandled) \
return TRUE; \
}
#define REFLECTED_COMMAND_CODE_HANDLER(code, func) \
if(uMsg == OCM_COMMAND && code == HIWORD(wParam)) \
{ \
bHandled = TRUE; \
lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
if(bHandled) \
return TRUE; \
}
#define REFLECTED_COMMAND_RANGE_HANDLER(idFirst, idLast, func) \
if(uMsg == OCM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
{ \
bHandled = TRUE; \
lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
if(bHandled) \
return TRUE; \
}
#define REFLECTED_COMMAND_RANGE_CODE_HANDLER(idFirst, idLast, code, func) \
if(uMsg == OCM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
{ \
bHandled = TRUE; \
lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
if(bHandled) \
return TRUE; \
}
#define REFLECTED_NOTIFY_HANDLER(id, cd, func) \
if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \
{ \
bHandled = TRUE; \
lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
if(bHandled) \
return TRUE; \
}
#define REFLECTED_NOTIFY_ID_HANDLER(id, func) \
if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \
{ \
bHandled = TRUE; \
lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
if(bHandled) \
return TRUE; \
}
#define REFLECTED_NOTIFY_CODE_HANDLER(cd, func) \
if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
{ \
bHandled = TRUE; \
lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
if(bHandled) \
return TRUE; \
}
#define REFLECTED_NOTIFY_RANGE_HANDLER(idFirst, idLast, func) \
if(uMsg == OCM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
{ \
bHandled = TRUE; \
lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
if(bHandled) \
return TRUE; \
}
#define REFLECTED_NOTIFY_RANGE_CODE_HANDLER(idFirst, idLast, cd, func) \
if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
{ \
bHandled = TRUE; \
lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
if(bHandled) \
return TRUE; \
}
#endif //(_ATL_VER < 0x0700)
/////////////////////////////////////////////////////////////////////////////
// General DLL version helpers (excluded from atlbase.h if _ATL_DLL is defined)
#if (_ATL_VER < 0x0700) && defined(_ATL_DLL)
inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo)
{
ATLASSERT(pDllVersionInfo != NULL);
if(pDllVersionInfo == NULL)
return E_INVALIDARG;
// We must get this function explicitly because some DLLs don't implement it.
DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion");
if(pfnDllGetVersion == NULL)
return E_NOTIMPL;
return (*pfnDllGetVersion)(pDllVersionInfo);
}
inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo)
{
HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName);
if(hInstDLL == NULL)
return E_FAIL;
HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo);
::FreeLibrary(hInstDLL);
return hRet;
}
// Common Control Versions:
// Win95/WinNT 4.0 maj=4 min=00
// IE 3.x maj=4 min=70
// IE 4.0 maj=4 min=71
inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
{
ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);
if(pdwMajor == NULL || pdwMinor == NULL)
return E_INVALIDARG;
DLLVERSIONINFO dvi;
::ZeroMemory(&dvi, sizeof(dvi));
dvi.cbSize = sizeof(dvi);
HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi);
if(SUCCEEDED(hRet))
{
*pdwMajor = dvi.dwMajorVersion;
*pdwMinor = dvi.dwMinorVersion;
}
else if(hRet == E_NOTIMPL)
{
// If DllGetVersion is not there, then the DLL is a version
// previous to the one shipped with IE 3.x
*pdwMajor = 4;
*pdwMinor = 0;
hRet = S_OK;
}
return hRet;
}
// Shell Versions:
// Win95/WinNT 4.0 maj=4 min=00
// IE 3.x, IE 4.0 without Web Integrated Desktop maj=4 min=00
// IE 4.0 with Web Integrated Desktop maj=4 min=71
// IE 4.01 with Web Integrated Desktop maj=4 min=72
inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
{
ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);
if(pdwMajor == NULL || pdwMinor == NULL)
return E_INVALIDARG;
DLLVERSIONINFO dvi;
::ZeroMemory(&dvi, sizeof(dvi));
dvi.cbSize = sizeof(dvi);
HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi);
if(SUCCEEDED(hRet))
{
*pdwMajor = dvi.dwMajorVersion;
*pdwMinor = dvi.dwMinorVersion;
}
else if(hRet == E_NOTIMPL)
{
// If DllGetVersion is not there, then the DLL is a version
// previous to the one shipped with IE 4.x
*pdwMajor = 4;
*pdwMinor = 0;
hRet = S_OK;
}
return hRet;
}
#endif //(_ATL_VER < 0x0700) && defined(_ATL_DLL)
/////////////////////////////////////////////////////////////////////////////
// 32-bit (alpha channel) bitmap resource helper
// Note: 32-bit (alpha channel) images work only on Windows XP with Common Controls version 6.
// If you want your app to work on older version of Windows, load non-alpha images if Common
// Controls version is less than 6.
inline bool AtlIsAlphaBitmapResource(_U_STRINGorID image)
{
HRSRC hResource = ::FindResource(_pModule->GetResourceInstance(), image.m_lpstr, RT_BITMAP);
ATLASSERT(hResource != NULL);
HGLOBAL hGlobal = ::LoadResource(_pModule->GetResourceInstance(), hResource);
ATLASSERT(hGlobal != NULL);
LPBITMAPINFOHEADER pBitmapInfoHeader = (LPBITMAPINFOHEADER)::LockResource(hGlobal);
ATLASSERT(pBitmapInfoHeader != NULL);
return (pBitmapInfoHeader->biBitCount == 32);
}
/////////////////////////////////////////////////////////////////////////////
// CString forward reference (enables CString use in atluser.h and atlgdi.h)
#if defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING)
#define _WTL_USE_CSTRING
#endif //defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING)
#ifdef _WTL_USE_CSTRING
class CString; // forward declaration (include atlmisc.h for the whole class)
#endif //_WTL_USE_CSTRING
}; //namespace WTL
// These are always included
#include <atluser.h>
#include <atlgdi.h>
#ifndef _WTL_NO_AUTOMATIC_NAMESPACE
using namespace WTL;
#endif //!_WTL_NO_AUTOMATIC_NAMESPACE
#endif // __ATLAPP_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -