📄 atlwince.h
字号:
// --- PPC/SmartPhone application window and helpers ---
#ifndef _WTL_CE_NO_APPWINDOW
///////////////////////////////////////////////////////////////////////////////
// CAppInfoBase - Helper for application state save/restore to registry
class CAppInfoBase
{
public:
ATL::CRegKey m_Key;
CAppInfoBase(ATL::_U_STRINGorID sAppKey)
{
m_Key.Create(HKEY_CURRENT_USER, sAppKey.m_lpstr);
ATLASSERT(m_Key.m_hKey);
}
template <class V>
LONG Save(V& val, ATL::_U_STRINGorID sName)
{
return ::RegSetValueEx(m_Key, sName.m_lpstr, 0, REG_BINARY, (LPBYTE)&val, sizeof(V));
}
template <class V>
LONG Save(int nb, V& val0, ATL::_U_STRINGorID sName)
{
return ::RegSetValueEx(m_Key, sName.m_lpstr, 0, REG_BINARY, (LPBYTE)&val0, nb * sizeof(V));
}
template <class V>
LONG Restore(V& val, ATL::_U_STRINGorID sName)
{
DWORD valtype;
DWORD bufSize = sizeof(V);
return ::RegQueryValueEx(m_Key, sName.m_lpstr, 0, &valtype, (LPBYTE)&val, &bufSize);
}
template <class V>
LONG Restore(int nb, V& val0, ATL::_U_STRINGorID sName)
{
DWORD valtype;
DWORD bufSize = nb * sizeof(V);
return ::RegQueryValueEx(m_Key, sName.m_lpstr, 0, &valtype, (LPBYTE)&val0, &bufSize);
}
#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
#if (_ATL_VER < 0x0800)
LONG Save(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName)
{
return m_Key.SetValue(sval, sName.m_lpstr);
}
LONG Restore(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName)
{
DWORD size = MAX_PATH;
LONG res = m_Key.QueryValue(sval.GetBuffer(size), sName.m_lpstr, &size);
sval.ReleaseBuffer();
return res;
}
#else // !(_ATL_VER < 0x0800)
LONG Save(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName)
{
return m_Key.SetStringValue(sName.m_lpstr, sval);
}
LONG Restore(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName)
{
DWORD size = MAX_PATH;
LONG res = m_Key.QueryStringValue(sName.m_lpstr, sval.GetBuffer(size), &size);
sval.ReleaseBuffer();
return res;
}
#endif // !(_ATL_VER < 0x0800)
#else
#pragma message("Warning: CAppInfoBase compiles without CString support. Do not use CString in Save or Restore.")
#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
#if (_ATL_VER < 0x0800)
LONG Save(LPCTSTR sval, ATL::_U_STRINGorID sName)
{
return m_Key.SetValue(sval, sName.m_lpstr);
}
LONG Restore(LPTSTR sval, ATL::_U_STRINGorID sName, DWORD *plength)
{
return m_Key.QueryValue(sval, sName.m_lpstr, plength);
}
#else // !(_ATL_VER < 0x0800)
LONG Save(LPCTSTR sval, ATL::_U_STRINGorID sName)
{
return m_Key.SetStringValue(sName.m_lpstr, sval);
}
LONG Restore(LPTSTR sval, ATL::_U_STRINGorID sName, DWORD *plength)
{
return m_Key.QueryStringValue(sName.m_lpstr, sval, plength);
}
#endif // !(_ATL_VER < 0x0800)
LONG Delete(ATL::_U_STRINGorID sName)
{
return m_Key.DeleteValue(sName.m_lpstr);
}
};
///////////////////////////////////////////////////////////////////////////////
// CAppInfoT - CAppInfoBase constructed from a class with T::GetAppKey()
// Macro for declaring AppKey
#define DECLARE_APPKEY(uAppKey) \
static LPCTSTR GetAppKey() \
{ \
static LPCTSTR sAppKey = ATL::_U_STRINGorID(uAppKey).m_lpstr; \
return sAppKey; \
}
template <class T>
class CAppInfoT : public CAppInfoBase
{
public:
CAppInfoT() : CAppInfoBase(T::GetAppKey()){}
};
///////////////////////////////////////////////////////////////////////////////
// CAppWindowBase - Base class for PPC/SmartPhone "well-behaved" application window or dialog
// Macros for declaring frame WNDCLASS and AppKey
#define DECLARE_APP_FRAME_CLASS(WndClassName, uCommonResourceID, uAppKey) \
DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \
DECLARE_APPKEY(uAppKey)
#define DECLARE_APP_FRAME_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd, uAppKey) \
DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \
DECLARE_APPKEY(uAppKey)
template <class T>
class CAppWindowBase
{
public:
typedef class CAppInfoT< T > CAppInfo;
#ifndef WIN32_PLATFORM_WFSP
SHACTIVATEINFO m_sai; // NoOp on SmartPhones
#endif // WIN32_PLATFORM_WFSP
bool m_bHibernate;
CAppWindowBase< T >() : m_bHibernate(false)
{
#ifndef WIN32_PLATFORM_WFSP
SHACTIVATEINFO sai = { sizeof(SHACTIVATEINFO) };
m_sai = sai;
#endif // WIN32_PLATFORM_WFSP
};
// Same as WTL 7.1 AppWizard generated ActivatePreviousInstance + SendMessage WM_COPYDATA
static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR lpstrCmdLine, bool bDialog)
{
// requires T does DECLARE_APP_FRAME_CLASS, DECLARE_APP_FRAME_CLASS_EX or DECLARE_APP_DLG_CLASS
CFrameWndClassInfo& classInfo = T::GetWndClassInfo();
ATLVERIFY(::LoadString(hInstance, classInfo.m_uCommonResourceID, classInfo.m_szAutoName, sizeof(classInfo.m_szAutoName)/sizeof(classInfo.m_szAutoName[0])) != 0);
classInfo.m_wc.lpszClassName = classInfo.m_szAutoName;
const TCHAR* pszClass = classInfo.m_wc.lpszClassName;
if(NULL == pszClass || '\0' == *pszClass)
{
return E_FAIL;
}
const DWORD dRetryInterval = 100;
const int iMaxRetries = 25;
for(int i = 0; i < iMaxRetries; ++i)
{
HANDLE hMutex = CreateMutex(NULL, FALSE, pszClass);
DWORD dw = GetLastError();
if(NULL == hMutex)
{
HRESULT hr;
switch(dw)
{
case ERROR_INVALID_HANDLE:
// A non-mutext object with this name already exists.
hr = E_INVALIDARG;
break;
default:
// This should never happen...
hr = E_FAIL;
}
return hr;
}
// If the mutex already exists, then there should be another instance running
if(dw == ERROR_ALREADY_EXISTS)
{
CloseHandle(hMutex);
HWND hwnd = NULL;
if (bDialog)
hwnd = FindWindow(NULL, pszClass);
else
hwnd = FindWindow(pszClass, NULL);
if(hwnd == NULL)
{
Sleep(dRetryInterval);
continue;
}
else
{
// Transmit our params to previous instance
if (lpstrCmdLine && *lpstrCmdLine)
{
COPYDATASTRUCT cd = { NULL, sizeof(TCHAR) * (wcslen(lpstrCmdLine) + 1), (PVOID)lpstrCmdLine };
::SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)&cd);
}
// Set the previous instance as the foreground window
if(0 != SetForegroundWindow(reinterpret_cast<HWND>(reinterpret_cast<ULONG>(hwnd) | 0x1)))
return S_FALSE;
}
}
else
{
return S_OK;
}
}
return S_OK;
}
// Operations overriden in derived class
bool AppHibernate(bool /*bHibernate*/)
{
return false;
}
bool AppNewInstance(LPCTSTR /*lpstrCmdLine*/)
{
return false;
}
void AppSave()
{
}
#ifdef WIN32_PLATFORM_WFSP
void AppBackKey()
{
::SHNavigateBack();
}
#endif
// Message map and handlers
BEGIN_MSG_MAP(CAppWindowBase)
MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
#ifdef WIN32_PLATFORM_WFSP
MESSAGE_HANDLER(WM_HOTKEY, OnHotKey)
#else
MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
#endif // WIN32_PLATFORM_WFSP
MESSAGE_HANDLER(WM_HIBERNATE, OnHibernate)
MESSAGE_HANDLER(WM_COPYDATA, OnNewInstance)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
END_MSG_MAP()
LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
if (m_bHibernate)
m_bHibernate = pT->AppHibernate(false);
#ifndef WIN32_PLATFORM_WFSP
::SHHandleWMActivate(pT->m_hWnd, wParam, lParam, &m_sai, 0);
#else
wParam;
lParam;
#endif // WIN32_PLATFORM_WFSP
return bHandled = FALSE;
}
#ifdef WIN32_PLATFORM_WFSP
// SmartPhone VK_TBACK key standard management
LRESULT OnHotKey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
const UINT uModif = (UINT)LOWORD(lParam);
const UINT uVirtKey = (UINT)HIWORD(lParam);
if(uVirtKey == VK_TBACK)
if (AtlIsEditFocus())
::SHSendBackToFocusWindow(uMsg, wParam, lParam);
else if (uModif & MOD_KEYUP)
pT->AppBackKey();
return 1;
}
#else // !WIN32_PLATFORM_WFSP
// PPC SIP handling
LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
bHandled = FALSE;
return ::SHHandleWMSettingChange(pT->m_hWnd, wParam, lParam, &m_sai);
}
#endif // !WIN32_PLATFORM_WFSP
LRESULT OnHibernate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
return m_bHibernate = pT->AppHibernate(true);
}
LRESULT OnNewInstance(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam;
return pT->AppNewInstance((LPCTSTR)pcds->lpData);
}
LRESULT OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
pT->AppSave();
bHandled = FALSE;
return 1;
}
};
///////////////////////////////////////////////////////////////////////////////
// CAppWindow - PPC/SmartPhone "well-behaved" application window class
template <class T>
class CAppWindow : public CAppWindowBase< T >
{
public:
// Same as WTL 7.1 AppWizard generated Run + lpstrCmdLine in CreateEx
static int AppRun(LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWNORMAL)
{
CMessageLoop theLoop;
_Module.AddMessageLoop(&theLoop);
T wndMain;
if(wndMain.CreateEx(NULL, NULL, 0, 0, lpstrCmdLine) == NULL)
{
ATLTRACE2(atlTraceUI, 0, _T("Main window creation failed!\n"));
return 0;
}
wndMain.ShowWindow(nCmdShow);
int nRet = theLoop.Run();
_Module.RemoveMessageLoop();
return nRet;
}
static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR lpstrCmdLine)
{
return CAppWindowBase< T >::ActivatePreviousInstance(hInstance, lpstrCmdLine, false);
}
};
#ifndef _WTL_CE_NO_DIALOGS
///////////////////////////////////////////////////////////////////////////////
// CAppDialog - PPC/SmartPhone "well-behaved" dialog application class
// Macro for declaring dialog WNDCLASS and AppKey
#define DECLARE_APP_DLG_CLASS(WndClassName, uCommonResourceID, uAppKey) \
static WTL::CFrameWndClassInfo& GetWndClassInfo() \
{ \
static WTL::CFrameWndClassInfo wc = \
{ \
{ 0, (WNDPROC)StartDialogProc, \
0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName }, \
NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
}; \
return wc; \
}; \
DECLARE_APPKEY(uAppKey)
template <class T>
class CAppDialog : public CAppWindowBase< T >
{
public:
static int AppRun(LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWNORMAL)
{
CMessageLoop theLoop;
_Module.AddMessageLoop(&theLoop);
T dlgMain;
if(dlgMain.Create(NULL, (LPARAM)lpstrCmdLine) == NULL)
{
ATLTRACE2(atlTraceUI, 0, _T("Main dialog creation failed!\n"));
return 0;
}
dlgMain.ShowWindow(nCmdShow);
int nRet = theLoop.Run();
_Module.RemoveMessageLoop();
return nRet;
}
static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR lpstrCmdLine)
{
return CAppWindowBase< T >::ActivatePreviousInstance(hInstance, lpstrCmdLine, true);
};
};
// PPC/SmartPhone standard application dialogs
#ifdef WIN32_PLATFORM_WFSP
#define WTL_APP_SHIDIF WTL_SP_SHIDIF
#else
#define WTL_APP_SHIDIF WTL_STD_SHIDIF
#endif
///////////////////////////////////////////////////////////////////////////////
// CAppStdDialogImplBase - Base implementation of standard application dialogs
template <class T, class TImplBase, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
class ATL_NO_VTABLE CAppStdDialogImplBase :
public TImplBase,
public CAppDialog< T >
{
public:
WTL_DLG_NOTITLE;
void StdCloseDialog(int nVal)
{
T* pT = static_cast<T*>(this);
if (nVal != IDCANCEL)
pT->AppSave();
if (t_bModal == false)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -