/thirdparty/wtl/atlframe.h
http://crashrpt.googlecode.com/ · C Header · 3678 lines · 2942 code · 488 blank · 248 comment · 704 complexity · 418035ec778967ae3632c7f33f3fcf3c MD5 · raw file
Large files are truncated click here to view the full file
- // Windows Template Library - WTL version 8.1
- // Copyright (C) Microsoft Corporation. All rights reserved.
- //
- // This file is a part of the Windows Template Library.
- // The use and distribution terms for this software are covered by the
- // Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
- // which can be found in the file CPL.TXT at the root of this distribution.
- // By using this software in any fashion, you are agreeing to be bound by
- // the terms of this license. You must not remove this notice, or
- // any other, from this software.
-
- #ifndef __ATLFRAME_H__
- #define __ATLFRAME_H__
-
- #pragma once
-
- #ifndef __ATLAPP_H__
- #error atlframe.h requires atlapp.h to be included first
- #endif
-
- #ifndef __ATLWIN_H__
- #error atlframe.h requires atlwin.h to be included first
- #endif
-
-
- ///////////////////////////////////////////////////////////////////////////////
- // Classes in this file:
- //
- // CFrameWindowImpl<T, TBase, TWinTraits>
- // CMDIWindow
- // CMDIFrameWindowImpl<T, TBase, TWinTraits>
- // CMDIChildWindowImpl<T, TBase, TWinTraits>
- // COwnerDraw<T>
- // CUpdateUIBase
- // CUpdateUI<T>
- // CDynamicUpdateUI<T>
- // CAutoUpdateUI<T>
- // CDialogResize<T>
- // CDoubleBufferImpl<T>
- // CDoubleBufferWindowImpl<T, TBase, TWinTraits>
- //
- // Global functions:
- // AtlCreateSimpleToolBar()
-
-
- namespace WTL
- {
-
- ///////////////////////////////////////////////////////////////////////////////
- // CFrameWndClassInfo - Manages frame window Windows class information
-
- class CFrameWndClassInfo
- {
- public:
- #ifndef _WIN32_WCE
- enum { cchAutoName = 5 + sizeof(void*) * 2 }; // sizeof(void*) * 2 is the number of digits %p outputs
- WNDCLASSEX m_wc;
- #else // CE specific
- enum { cchAutoName = MAX_PATH }; // MAX_PATH because this can be set in the wizard generated CMainFrame::ActivatePreviousInstance to a user defined string.
- WNDCLASS m_wc;
- #endif // !_WIN32_WCE
- LPCTSTR m_lpszOrigName;
- WNDPROC pWndProc;
- LPCTSTR m_lpszCursorID;
- BOOL m_bSystemCursor;
- ATOM m_atom;
- TCHAR m_szAutoName[cchAutoName];
- UINT m_uCommonResourceID;
-
- #ifndef _WIN32_WCE
- ATOM Register(WNDPROC* pProc)
- {
- if (m_atom == 0)
- {
- CWindowCreateCriticalSectionLock lock;
- if(FAILED(lock.Lock()))
- {
- ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CFrameWndClassInfo::Register.\n"));
- ATLASSERT(FALSE);
- return 0;
- }
-
- if(m_atom == 0)
- {
- HINSTANCE hInst = ModuleHelper::GetModuleInstance();
-
- if (m_lpszOrigName != NULL)
- {
- ATLASSERT(pProc != NULL);
- LPCTSTR lpsz = m_wc.lpszClassName;
- WNDPROC proc = m_wc.lpfnWndProc;
-
- WNDCLASSEX wc = { sizeof(WNDCLASSEX) };
- // try process local class first
- if(!::GetClassInfoEx(ModuleHelper::GetModuleInstance(), m_lpszOrigName, &wc))
- {
- // try global class
- if(!::GetClassInfoEx(NULL, m_lpszOrigName, &wc))
- {
- lock.Unlock();
- return 0;
- }
- }
- m_wc = wc;
- pWndProc = m_wc.lpfnWndProc;
- m_wc.lpszClassName = lpsz;
- m_wc.lpfnWndProc = proc;
- }
- else
- {
- m_wc.hCursor = ::LoadCursor(m_bSystemCursor ? NULL : hInst, m_lpszCursorID);
- }
-
- m_wc.hInstance = hInst;
- m_wc.style &= ~CS_GLOBALCLASS; // we don't register global classes
- if (m_wc.lpszClassName == NULL)
- {
- #if (_WIN32_WINNT >= 0x0500) || defined(_WIN64)
- SecureHelper::wsprintf_x(m_szAutoName, cchAutoName, _T("ATL:%p"), &m_wc);
- #else // !((_WIN32_WINNT >= 0x0500) || defined(_WIN64))
- SecureHelper::wsprintf_x(m_szAutoName, cchAutoName, _T("ATL:%8.8X"), (DWORD_PTR)&m_wc);
- #endif // !((_WIN32_WINNT >= 0x0500) || defined(_WIN64))
- m_wc.lpszClassName = m_szAutoName;
- }
-
- WNDCLASSEX wcTemp = m_wc;
- m_atom = (ATOM)::GetClassInfoEx(m_wc.hInstance, m_wc.lpszClassName, &wcTemp);
- if (m_atom == 0)
- {
- if(m_uCommonResourceID != 0) // use it if not zero
- {
- m_wc.hIcon = (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
- m_wc.hIconSm = (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
- }
- m_atom = ::RegisterClassEx(&m_wc);
- }
- }
-
- lock.Unlock();
- }
-
- if (m_lpszOrigName != NULL)
- {
- ATLASSERT(pProc != NULL);
- ATLASSERT(pWndProc != NULL);
- *pProc = pWndProc;
- }
-
- return m_atom;
- }
- #else // CE specific
- ATOM Register(WNDPROC* pProc)
- {
- if (m_atom == 0)
- {
- CWindowCreateCriticalSectionLock lock;
- if(FAILED(lock.Lock()))
- {
- ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CFrameWndClassInfo::Register.\n"));
- ATLASSERT(FALSE);
- return 0;
- }
-
- if(m_atom == 0)
- {
- HINSTANCE hInst = ModuleHelper::GetModuleInstance();
-
- if (m_lpszOrigName != NULL)
- {
- ATLASSERT(pProc != NULL);
- LPCTSTR lpsz = m_wc.lpszClassName;
- WNDPROC proc = m_wc.lpfnWndProc;
-
- WNDCLASS wc = { 0 };
- // try process local class first
- if(!::GetClassInfo(ModuleHelper::GetModuleInstance(), m_lpszOrigName, &wc))
- {
- // try global class
- if(!::GetClassInfo(NULL, m_lpszOrigName, &wc))
- {
- lock.Unlock();
- return 0;
- }
- }
- m_wc = wc;
- pWndProc = m_wc.lpfnWndProc;
- m_wc.lpszClassName = lpsz;
- m_wc.lpfnWndProc = proc;
- }
- else
- {
- #if defined(GWES_CURSOR) || defined(GWES_MCURSOR)
- m_wc.hCursor = ::LoadCursor(m_bSystemCursor ? NULL : hInst, m_lpszCursorID);
- #else // !(defined(GWES_CURSOR) || defined(GWES_MCURSOR))
- m_wc.hCursor = NULL;
- #endif // !(defined(GWES_CURSOR) || defined(GWES_MCURSOR))
- }
-
- m_wc.hInstance = hInst;
- m_wc.style &= ~CS_GLOBALCLASS; // we don't register global classes
- if (m_wc.lpszClassName == NULL)
- {
- wsprintf(m_szAutoName, _T("ATL:%8.8X"), (DWORD_PTR)&m_wc);
- m_wc.lpszClassName = m_szAutoName;
- }
-
- WNDCLASS wcTemp = m_wc;
- m_atom = (ATOM)::GetClassInfo(m_wc.hInstance, m_wc.lpszClassName, &wcTemp);
- if (m_atom == 0)
- {
- if(m_uCommonResourceID != 0) // use it if not zero
- m_wc.hIcon = (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
- m_atom = ::RegisterClass(&m_wc);
- }
- }
-
- lock.Unlock();
- }
-
- if (m_lpszOrigName != NULL)
- {
- ATLASSERT(pProc != NULL);
- ATLASSERT(pWndProc != NULL);
- *pProc = pWndProc;
- }
-
- return m_atom;
- }
- #endif // _WIN32_WCE
- };
-
-
- ///////////////////////////////////////////////////////////////////////////////
- // Macros for declaring frame window WNDCLASS
-
- #ifndef _WIN32_WCE
-
- #define DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \
- static WTL::CFrameWndClassInfo& GetWndClassInfo() \
- { \
- static WTL::CFrameWndClassInfo wc = \
- { \
- { sizeof(WNDCLASSEX), 0, StartWindowProc, \
- 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName, NULL }, \
- NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
- }; \
- return wc; \
- }
-
- #define DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \
- static WTL::CFrameWndClassInfo& GetWndClassInfo() \
- { \
- static WTL::CFrameWndClassInfo wc = \
- { \
- { sizeof(WNDCLASSEX), style, StartWindowProc, \
- 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL }, \
- NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
- }; \
- return wc; \
- }
-
- #define DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonResourceID) \
- static WTL::CFrameWndClassInfo& GetWndClassInfo() \
- { \
- static WTL::CFrameWndClassInfo wc = \
- { \
- { sizeof(WNDCLASSEX), 0, StartWindowProc, \
- 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName, NULL }, \
- OrigWndClassName, NULL, NULL, TRUE, 0, _T(""), uCommonResourceID \
- }; \
- return wc; \
- }
-
- #else // CE specific
-
- #define DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \
- static WTL::CFrameWndClassInfo& GetWndClassInfo() \
- { \
- static WTL::CFrameWndClassInfo wc = \
- { \
- { 0, StartWindowProc, \
- 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName }, \
- NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
- }; \
- return wc; \
- }
-
- #define DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \
- static WTL::CFrameWndClassInfo& GetWndClassInfo() \
- { \
- static WTL::CFrameWndClassInfo wc = \
- { \
- { style, StartWindowProc, \
- 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName }, \
- NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
- }; \
- return wc; \
- }
-
- #define DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonResourceID) \
- static WTL::CFrameWndClassInfo& GetWndClassInfo() \
- { \
- static WTL::CFrameWndClassInfo wc = \
- { \
- { NULL, StartWindowProc, \
- 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName }, \
- OrigWndClassName, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
- }; \
- return wc; \
- }
-
- #endif // !_WIN32_WCE
-
-
- ///////////////////////////////////////////////////////////////////////////////
- // CFrameWindowImpl
-
- // Client window command chaining macro (only for frame windows)
- #define CHAIN_CLIENT_COMMANDS() \
- if(uMsg == WM_COMMAND && m_hWndClient != NULL) \
- ::SendMessage(m_hWndClient, uMsg, wParam, lParam);
-
- // standard toolbar styles
- #define ATL_SIMPLE_TOOLBAR_STYLE \
- (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS)
- // toolbar in a rebar pane
- #define ATL_SIMPLE_TOOLBAR_PANE_STYLE \
- (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NORESIZE | CCS_NOPARENTALIGN | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT)
- // standard rebar styles
- #if (_WIN32_IE >= 0x0400)
- #define ATL_SIMPLE_REBAR_STYLE \
- (WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE)
- #else
- #define ATL_SIMPLE_REBAR_STYLE \
- (WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS)
- #endif // !(_WIN32_IE >= 0x0400)
- // rebar without borders
- #if (_WIN32_IE >= 0x0400)
- #define ATL_SIMPLE_REBAR_NOBORDER_STYLE \
- (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE | CCS_NODIVIDER)
- #else
- #define ATL_SIMPLE_REBAR_NOBORDER_STYLE \
- (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | CCS_NODIVIDER)
- #endif // !(_WIN32_IE >= 0x0400)
-
- // command bar support
- #if !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE)
-
- #define CBRM_GETCMDBAR (WM_USER + 301) // returns command bar HWND
- #define CBRM_GETMENU (WM_USER + 302) // returns loaded or attached menu
- #define CBRM_TRACKPOPUPMENU (WM_USER + 303) // displays a popup menu
-
- struct _AtlFrameWnd_CmdBarPopupMenu
- {
- int cbSize;
- HMENU hMenu;
- UINT uFlags;
- int x;
- int y;
- LPTPMPARAMS lptpm;
- };
-
- #define CBRPOPUPMENU _AtlFrameWnd_CmdBarPopupMenu
-
- #endif // !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE)
-
-
- template <class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWinTraits>
- class ATL_NO_VTABLE CFrameWindowImplBase : public ATL::CWindowImplBaseT< TBase, TWinTraits >
- {
- public:
- DECLARE_FRAME_WND_CLASS(NULL, 0)
-
- #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
- struct _ChevronMenuInfo
- {
- HMENU hMenu;
- LPNMREBARCHEVRON lpnm;
- bool bCmdBar;
- };
- #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
-
- // Data members
- HWND m_hWndToolBar;
- HWND m_hWndStatusBar;
- HWND m_hWndClient;
-
- #ifdef _WIN32_WCE
- HWND m_hWndCECommandBar;
- #endif // _WIN32_WCE
-
- HACCEL m_hAccel;
-
- // Constructor
- CFrameWindowImplBase() :
- m_hWndToolBar(NULL),
- m_hWndStatusBar(NULL),
- m_hWndClient(NULL),
- #ifdef _WIN32_WCE
- m_hWndCECommandBar(NULL),
- #endif // _WIN32_WCE
- m_hAccel(NULL)
- { }
-
- // Methods
- HWND Create(HWND hWndParent, ATL::_U_RECT rect, LPCTSTR szWindowName, DWORD dwStyle, DWORD dwExStyle, ATL::_U_MENUorID MenuOrID, ATOM atom, LPVOID lpCreateParam)
- {
- ATLASSERT(m_hWnd == NULL);
-
- if(atom == 0)
- return NULL;
-
- ModuleHelper::AddCreateWndData(&m_thunk.cd, this);
-
- if(MenuOrID.m_hMenu == NULL && (dwStyle & WS_CHILD))
- MenuOrID.m_hMenu = (HMENU)(UINT_PTR)this;
- if(rect.m_lpRect == NULL)
- rect.m_lpRect = &TBase::rcDefault;
-
- HWND hWnd = ::CreateWindowEx(dwExStyle, MAKEINTATOM(atom), szWindowName,
- dwStyle, rect.m_lpRect->left, rect.m_lpRect->top, rect.m_lpRect->right - rect.m_lpRect->left,
- rect.m_lpRect->bottom - rect.m_lpRect->top, hWndParent, MenuOrID.m_hMenu,
- ModuleHelper::GetModuleInstance(), lpCreateParam);
-
- ATLASSERT(hWnd == NULL || m_hWnd == hWnd);
-
- return hWnd;
- }
-
- static HWND CreateSimpleToolBarCtrl(HWND hWndParent, UINT nResourceID, BOOL bInitialSeparator = FALSE,
- DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
- {
- HINSTANCE hInst = ModuleHelper::GetResourceInstance();
- HRSRC hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(nResourceID), RT_TOOLBAR);
- if (hRsrc == NULL)
- return NULL;
-
- HGLOBAL hGlobal = ::LoadResource(hInst, hRsrc);
- if (hGlobal == NULL)
- return NULL;
-
- _AtlToolBarData* pData = (_AtlToolBarData*)::LockResource(hGlobal);
- if (pData == NULL)
- return NULL;
- ATLASSERT(pData->wVersion == 1);
-
- WORD* pItems = pData->items();
- int nItems = pData->wItemCount + (bInitialSeparator ? 1 : 0);
- CTempBuffer<TBBUTTON, _WTL_STACK_ALLOC_THRESHOLD> buff;
- TBBUTTON* pTBBtn = buff.Allocate(nItems);
- ATLASSERT(pTBBtn != NULL);
- if(pTBBtn == NULL)
- return NULL;
-
- const int cxSeparator = 8;
-
- // set initial separator (half width)
- if(bInitialSeparator)
- {
- pTBBtn[0].iBitmap = cxSeparator / 2;
- pTBBtn[0].idCommand = 0;
- pTBBtn[0].fsState = 0;
- pTBBtn[0].fsStyle = TBSTYLE_SEP;
- pTBBtn[0].dwData = 0;
- pTBBtn[0].iString = 0;
- }
-
- int nBmp = 0;
- for(int i = 0, j = bInitialSeparator ? 1 : 0; i < pData->wItemCount; i++, j++)
- {
- if(pItems[i] != 0)
- {
- pTBBtn[j].iBitmap = nBmp++;
- pTBBtn[j].idCommand = pItems[i];
- pTBBtn[j].fsState = TBSTATE_ENABLED;
- pTBBtn[j].fsStyle = TBSTYLE_BUTTON;
- pTBBtn[j].dwData = 0;
- pTBBtn[j].iString = 0;
- }
- else
- {
- pTBBtn[j].iBitmap = cxSeparator;
- pTBBtn[j].idCommand = 0;
- pTBBtn[j].fsState = 0;
- pTBBtn[j].fsStyle = TBSTYLE_SEP;
- pTBBtn[j].dwData = 0;
- pTBBtn[j].iString = 0;
- }
- }
-
- #ifndef _WIN32_WCE
- HWND hWnd = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, dwStyle, 0, 0, 100, 100, hWndParent, (HMENU)LongToHandle(nID), ModuleHelper::GetModuleInstance(), NULL);
- if(hWnd == NULL)
- {
- ATLASSERT(FALSE);
- return NULL;
- }
- #else // CE specific
- dwStyle;
- nID;
- // The toolbar must go onto the existing CommandBar or MenuBar
- HWND hWnd = hWndParent;
- #endif // _WIN32_WCE
-
- ::SendMessage(hWnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0L);
-
- // check if font is taller than our bitmaps
- CFontHandle font = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L);
- if(font.IsNull())
- font = (HFONT)::GetStockObject(SYSTEM_FONT);
- LOGFONT lf = { 0 };
- font.GetLogFont(lf);
- WORD cyFontHeight = (WORD)abs(lf.lfHeight);
-
- #ifndef _WIN32_WCE
- WORD bitsPerPixel = AtlGetBitmapResourceBitsPerPixel(nResourceID);
- if(bitsPerPixel > 4)
- {
- COLORREF crMask = CLR_DEFAULT;
- if(bitsPerPixel == 32)
- {
- // 32-bit color bitmap with alpha channel (valid for Windows XP and later)
- crMask = CLR_NONE;
- }
- HIMAGELIST hImageList = ImageList_LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(nResourceID), pData->wWidth, 1, crMask, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
- ATLASSERT(hImageList != NULL);
- ::SendMessage(hWnd, TB_SETIMAGELIST, 0, (LPARAM)hImageList);
- }
- else
- #endif // !_WIN32_WCE
- {
- TBADDBITMAP tbab = { 0 };
- tbab.hInst = hInst;
- tbab.nID = nResourceID;
- ::SendMessage(hWnd, TB_ADDBITMAP, nBmp, (LPARAM)&tbab);
- }
-
- ::SendMessage(hWnd, TB_ADDBUTTONS, nItems, (LPARAM)pTBBtn);
- ::SendMessage(hWnd, TB_SETBITMAPSIZE, 0, MAKELONG(pData->wWidth, max(pData->wHeight, cyFontHeight)));
- const int cxyButtonMargin = 7;
- ::SendMessage(hWnd, TB_SETBUTTONSIZE, 0, MAKELONG(pData->wWidth + cxyButtonMargin, max(pData->wHeight, cyFontHeight) + cxyButtonMargin));
-
- return hWnd;
- }
-
- #ifndef _WIN32_WCE
- static HWND CreateSimpleReBarCtrl(HWND hWndParent, DWORD dwStyle = ATL_SIMPLE_REBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
- {
- // Ensure style combinations for proper rebar painting
- if(dwStyle & CCS_NODIVIDER && dwStyle & WS_BORDER)
- dwStyle &= ~WS_BORDER;
- else if(!(dwStyle & WS_BORDER) && !(dwStyle & CCS_NODIVIDER))
- dwStyle |= CCS_NODIVIDER;
-
- // Create rebar window
- HWND hWndReBar = ::CreateWindowEx(0, REBARCLASSNAME, NULL, dwStyle, 0, 0, 100, 100, hWndParent, (HMENU)LongToHandle(nID), ModuleHelper::GetModuleInstance(), NULL);
- if(hWndReBar == NULL)
- {
- ATLTRACE2(atlTraceUI, 0, _T("Failed to create rebar.\n"));
- return NULL;
- }
-
- // Initialize and send the REBARINFO structure
- REBARINFO rbi = { sizeof(REBARINFO), 0 };
- if(::SendMessage(hWndReBar, RB_SETBARINFO, 0, (LPARAM)&rbi) == 0)
- {
- ATLTRACE2(atlTraceUI, 0, _T("Failed to initialize rebar.\n"));
- ::DestroyWindow(hWndReBar);
- return NULL;
- }
-
- return hWndReBar;
- }
-
- BOOL CreateSimpleReBar(DWORD dwStyle = ATL_SIMPLE_REBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
- {
- ATLASSERT(!::IsWindow(m_hWndToolBar));
- m_hWndToolBar = CreateSimpleReBarCtrl(m_hWnd, dwStyle, nID);
- return (m_hWndToolBar != NULL);
- }
-
- static BOOL AddSimpleReBarBandCtrl(HWND hWndReBar, HWND hWndBand, int nID = 0, LPCTSTR lpstrTitle = NULL, BOOL bNewRow = FALSE, int cxWidth = 0, BOOL bFullWidthAlways = FALSE)
- {
- ATLASSERT(::IsWindow(hWndReBar)); // must be already created
- #ifdef _DEBUG
- // block - check if this is really a rebar
- {
- TCHAR lpszClassName[sizeof(REBARCLASSNAME)] = { 0 };
- ::GetClassName(hWndReBar, lpszClassName, sizeof(REBARCLASSNAME));
- ATLASSERT(lstrcmp(lpszClassName, REBARCLASSNAME) == 0);
- }
- #endif // _DEBUG
- ATLASSERT(::IsWindow(hWndBand)); // must be already created
-
- // Get number of buttons on the toolbar
- int nBtnCount = (int)::SendMessage(hWndBand, TB_BUTTONCOUNT, 0, 0L);
-
- // Set band info structure
- REBARBANDINFO rbBand = { RunTimeHelper::SizeOf_REBARBANDINFO() };
- #if (_WIN32_IE >= 0x0400)
- rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE | RBBIM_IDEALSIZE;
- #else
- rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE;
- #endif // !(_WIN32_IE >= 0x0400)
- if(lpstrTitle != NULL)
- rbBand.fMask |= RBBIM_TEXT;
- rbBand.fStyle = RBBS_CHILDEDGE;
- #if (_WIN32_IE >= 0x0500)
- if(nBtnCount > 0) // add chevron style for toolbar with buttons
- rbBand.fStyle |= RBBS_USECHEVRON;
- #endif // (_WIN32_IE >= 0x0500)
- if(bNewRow)
- rbBand.fStyle |= RBBS_BREAK;
-
- rbBand.lpText = (LPTSTR)lpstrTitle;
- rbBand.hwndChild = hWndBand;
- if(nID == 0) // calc band ID
- nID = ATL_IDW_BAND_FIRST + (int)::SendMessage(hWndReBar, RB_GETBANDCOUNT, 0, 0L);
- rbBand.wID = nID;
-
- // Calculate the size of the band
- BOOL bRet = FALSE;
- RECT rcTmp = { 0 };
- if(nBtnCount > 0)
- {
- bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMRECT, nBtnCount - 1, (LPARAM)&rcTmp);
- ATLASSERT(bRet);
- rbBand.cx = (cxWidth != 0) ? cxWidth : rcTmp.right;
- rbBand.cyMinChild = rcTmp.bottom - rcTmp.top;
- if(bFullWidthAlways)
- {
- rbBand.cxMinChild = rbBand.cx;
- }
- else if(lpstrTitle == NULL)
- {
- bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMRECT, 0, (LPARAM)&rcTmp);
- ATLASSERT(bRet);
- rbBand.cxMinChild = rcTmp.right;
- }
- else
- {
- rbBand.cxMinChild = 0;
- }
- }
- else // no buttons, either not a toolbar or really has no buttons
- {
- bRet = ::GetWindowRect(hWndBand, &rcTmp);
- ATLASSERT(bRet);
- rbBand.cx = (cxWidth != 0) ? cxWidth : (rcTmp.right - rcTmp.left);
- rbBand.cxMinChild = bFullWidthAlways ? rbBand.cx : 0;
- rbBand.cyMinChild = rcTmp.bottom - rcTmp.top;
- }
-
- #if (_WIN32_IE >= 0x0400)
- rbBand.cxIdeal = rbBand.cx;
- #endif // (_WIN32_IE >= 0x0400)
-
- // Add the band
- LRESULT lRes = ::SendMessage(hWndReBar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
- if(lRes == 0)
- {
- ATLTRACE2(atlTraceUI, 0, _T("Failed to add a band to the rebar.\n"));
- return FALSE;
- }
-
- #if (_WIN32_IE >= 0x0501)
- DWORD dwExStyle = (DWORD)::SendMessage(hWndBand, TB_GETEXTENDEDSTYLE, 0, 0L);
- ::SendMessage(hWndBand, TB_SETEXTENDEDSTYLE, 0, dwExStyle | TBSTYLE_EX_HIDECLIPPEDBUTTONS);
- #endif // (_WIN32_IE >= 0x0501)
-
- return TRUE;
- }
-
- BOOL AddSimpleReBarBand(HWND hWndBand, LPCTSTR lpstrTitle = NULL, BOOL bNewRow = FALSE, int cxWidth = 0, BOOL bFullWidthAlways = FALSE)
- {
- ATLASSERT(::IsWindow(m_hWndToolBar)); // must be an existing rebar
- ATLASSERT(::IsWindow(hWndBand)); // must be created
- return AddSimpleReBarBandCtrl(m_hWndToolBar, hWndBand, 0, lpstrTitle, bNewRow, cxWidth, bFullWidthAlways);
- }
-
- #if (_WIN32_IE >= 0x0400)
- void SizeSimpleReBarBands()
- {
- ATLASSERT(::IsWindow(m_hWndToolBar)); // must be an existing rebar
-
- int nCount = (int)::SendMessage(m_hWndToolBar, RB_GETBANDCOUNT, 0, 0L);
-
- for(int i = 0; i < nCount; i++)
- {
- REBARBANDINFO rbBand = { RunTimeHelper::SizeOf_REBARBANDINFO() };
- rbBand.fMask = RBBIM_SIZE;
- BOOL bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_GETBANDINFO, i, (LPARAM)&rbBand);
- ATLASSERT(bRet);
- RECT rect = { 0, 0, 0, 0 };
- ::SendMessage(m_hWndToolBar, RB_GETBANDBORDERS, i, (LPARAM)&rect);
- rbBand.cx += rect.left + rect.right;
- bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_SETBANDINFO, i, (LPARAM)&rbBand);
- ATLASSERT(bRet);
- }
- }
- #endif // (_WIN32_IE >= 0x0400)
- #endif // _WIN32_WCE
-
- #ifndef _WIN32_WCE
- BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR)
- #else // CE specific
- BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, UINT nID = ATL_IDW_STATUS_BAR)
- #endif // _WIN32_WCE
- {
- ATLASSERT(!::IsWindow(m_hWndStatusBar));
- m_hWndStatusBar = ::CreateStatusWindow(dwStyle, lpstrText, m_hWnd, nID);
- return (m_hWndStatusBar != NULL);
- }
-
- #ifndef _WIN32_WCE
- BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR)
- #else // CE specific
- BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, UINT nID = ATL_IDW_STATUS_BAR)
- #endif // _WIN32_WCE
- {
- const int cchMax = 128; // max text length is 127 for status bars (+1 for null)
- TCHAR szText[cchMax] = { 0 };
- ::LoadString(ModuleHelper::GetResourceInstance(), nTextID, szText, cchMax);
- return CreateSimpleStatusBar(szText, dwStyle, nID);
- }
-
- #ifdef _WIN32_WCE
- BOOL CreateSimpleCECommandBar(LPTSTR pszMenu = NULL, WORD iButton = 0, DWORD dwFlags = 0, int nCmdBarID = 1)
- {
- ATLASSERT(m_hWndCECommandBar == NULL);
- ATLASSERT(m_hWndToolBar == NULL);
-
- m_hWndCECommandBar = ::CommandBar_Create(ModuleHelper::GetModuleInstance(), m_hWnd, nCmdBarID);
- if(m_hWndCECommandBar == NULL)
- return FALSE;
-
- m_hWndToolBar = m_hWndCECommandBar;
-
- BOOL bRet = TRUE;
-
- if(pszMenu != NULL)
- bRet &= ::CommandBar_InsertMenubarEx(m_hWndCECommandBar, IS_INTRESOURCE(pszMenu) ? ModuleHelper::GetResourceInstance() : NULL, pszMenu, iButton);
-
- bRet &= ::CommandBar_AddAdornments(m_hWndCECommandBar, dwFlags, 0);
-
- return bRet;
- }
-
- #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
- BOOL CreateSimpleCEMenuBar(UINT nToolBarId = ATL_IDW_MENU_BAR, DWORD dwFlags = 0, int nBmpId = 0, int cBmpImages = 0)
- {
- ATLASSERT(m_hWndCECommandBar == NULL);
-
- SHMENUBARINFO mbi = { 0 };
- mbi.cbSize = sizeof(mbi);
- mbi.hwndParent = m_hWnd;
- mbi.dwFlags = dwFlags;
- mbi.nToolBarId = nToolBarId;
- mbi.hInstRes = ModuleHelper::GetResourceInstance();
- mbi.nBmpId = nBmpId;
- mbi.cBmpImages = cBmpImages;
- mbi.hwndMB = NULL; // This gets set by SHCreateMenuBar
-
- BOOL bRet = ::SHCreateMenuBar(&mbi);
- if(bRet != FALSE)
- {
- m_hWndCECommandBar = mbi.hwndMB;
- SizeToMenuBar();
- }
-
- return bRet;
- }
-
- void SizeToMenuBar() // for menu bar only
- {
- ATLASSERT(::IsWindow(m_hWnd));
- ATLASSERT(::IsWindow(m_hWndCECommandBar));
-
- RECT rect = { 0 };
- GetWindowRect(&rect);
- RECT rectMB = { 0 };
- ::GetWindowRect(m_hWndCECommandBar, &rectMB);
- int cy = ::IsWindowVisible(m_hWndCECommandBar) ? rectMB.top - rect.top : rectMB.bottom - rect.top;
- SetWindowPos(NULL, 0, 0, rect.right - rect.left, cy, SWP_NOZORDER | SWP_NOMOVE);
- }
- #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
- #endif // _WIN32_WCE
-
- void UpdateLayout(BOOL bResizeBars = TRUE)
- {
- RECT rect = { 0 };
- GetClientRect(&rect);
-
- // position bars and offset their dimensions
- UpdateBarsPosition(rect, bResizeBars);
-
- // resize client window
- if(m_hWndClient != NULL)
- ::SetWindowPos(m_hWndClient, NULL, rect.left, rect.top,
- rect.right - rect.left, rect.bottom - rect.top,
- SWP_NOZORDER | SWP_NOACTIVATE);
- }
-
- void UpdateBarsPosition(RECT& rect, BOOL bResizeBars = TRUE)
- {
- // resize toolbar
- if(m_hWndToolBar != NULL && ((DWORD)::GetWindowLong(m_hWndToolBar, GWL_STYLE) & WS_VISIBLE))
- {
- if(bResizeBars != FALSE)
- {
- ::SendMessage(m_hWndToolBar, WM_SIZE, 0, 0);
- ::InvalidateRect(m_hWndToolBar, NULL, TRUE);
- }
- RECT rectTB = { 0 };
- ::GetWindowRect(m_hWndToolBar, &rectTB);
- rect.top += rectTB.bottom - rectTB.top;
- }
-
- // resize status bar
- if(m_hWndStatusBar != NULL && ((DWORD)::GetWindowLong(m_hWndStatusBar, GWL_STYLE) & WS_VISIBLE))
- {
- if(bResizeBars != FALSE)
- ::SendMessage(m_hWndStatusBar, WM_SIZE, 0, 0);
- RECT rectSB = { 0 };
- ::GetWindowRect(m_hWndStatusBar, &rectSB);
- rect.bottom -= rectSB.bottom - rectSB.top;
- }
- }
-
- BOOL PreTranslateMessage(MSG* pMsg)
- {
- if(m_hAccel != NULL && ::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
- return TRUE;
- return FALSE;
- }
-
- BEGIN_MSG_MAP(CFrameWindowImplBase)
- MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
- #ifndef _WIN32_WCE
- MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
- #endif // !_WIN32_WCE
- MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
- MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
- #ifndef _WIN32_WCE
- NOTIFY_CODE_HANDLER(TTN_GETDISPINFOA, OnToolTipTextA)
- NOTIFY_CODE_HANDLER(TTN_GETDISPINFOW, OnToolTipTextW)
- #endif // !_WIN32_WCE
- END_MSG_MAP()
-
- LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
- {
- if(m_hWndClient != NULL) // view will paint itself instead
- return 1;
-
- bHandled = FALSE;
- return 0;
- }
-
- #ifndef _WIN32_WCE
- LRESULT OnMenuSelect(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
- {
- bHandled = FALSE;
-
- if(m_hWndStatusBar == NULL)
- return 1;
-
- WORD wFlags = HIWORD(wParam);
- if(wFlags == 0xFFFF && lParam == NULL) // menu closing
- {
- ::SendMessage(m_hWndStatusBar, SB_SIMPLE, FALSE, 0L);
- }
- else
- {
- const int cchBuff = 256;
- TCHAR szBuff[cchBuff] = { 0 };
- if(!(wFlags & MF_POPUP))
- {
- WORD wID = LOWORD(wParam);
- // check for special cases
- if(wID >= 0xF000 && wID < 0xF1F0) // system menu IDs
- wID = (WORD)(((wID - 0xF000) >> 4) + ATL_IDS_SCFIRST);
- else if(wID >= ID_FILE_MRU_FIRST && wID <= ID_FILE_MRU_LAST) // MRU items
- wID = ATL_IDS_MRU_FILE;
- else if(wID >= ATL_IDM_FIRST_MDICHILD && wID <= ATL_IDM_LAST_MDICHILD) // MDI child windows
- wID = ATL_IDS_MDICHILD;
-
- int nRet = ::LoadString(ModuleHelper::GetResourceInstance(), wID, szBuff, cchBuff);
- for(int i = 0; i < nRet; i++)
- {
- if(szBuff[i] == _T('\n'))
- {
- szBuff[i] = 0;
- break;
- }
- }
- }
- ::SendMessage(m_hWndStatusBar, SB_SIMPLE, TRUE, 0L);
- ::SendMessage(m_hWndStatusBar, SB_SETTEXT, (255 | SBT_NOBORDERS), (LPARAM)szBuff);
- }
-
- return 1;
- }
- #endif // !_WIN32_WCE
-
- LRESULT OnSetFocus(UINT, WPARAM, LPARAM, BOOL& bHandled)
- {
- if(m_hWndClient != NULL)
- ::SetFocus(m_hWndClient);
-
- bHandled = FALSE;
- return 1;
- }
-
- LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL& bHandled)
- {
- if((GetStyle() & (WS_CHILD | WS_POPUP)) == 0)
- ::PostQuitMessage(1);
-
- bHandled = FALSE;
- return 1;
- }
-
- #ifndef _WIN32_WCE
- LRESULT OnToolTipTextA(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
- {
- LPNMTTDISPINFOA pDispInfo = (LPNMTTDISPINFOA)pnmh;
- pDispInfo->szText[0] = 0;
-
- if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND))
- {
- const int cchBuff = 256;
- char szBuff[cchBuff] = { 0 };
- int nRet = ::LoadStringA(ModuleHelper::GetResourceInstance(), idCtrl, szBuff, cchBuff);
- for(int i = 0; i < nRet; i++)
- {
- if(szBuff[i] == '\n')
- {
- SecureHelper::strncpyA_x(pDispInfo->szText, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE);
- break;
- }
- }
- #if (_WIN32_IE >= 0x0300)
- if(nRet > 0) // string was loaded, save it
- pDispInfo->uFlags |= TTF_DI_SETITEM;
- #endif // (_WIN32_IE >= 0x0300)
- }
-
- return 0;
- }
-
- LRESULT OnToolTipTextW(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
- {
- LPNMTTDISPINFOW pDispInfo = (LPNMTTDISPINFOW)pnmh;
- pDispInfo->szText[0] = 0;
-
- if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND))
- {
- const int cchBuff = 256;
- wchar_t szBuff[cchBuff] = { 0 };
- int nRet = ::LoadStringW(ModuleHelper::GetResourceInstance(), idCtrl, szBuff, cchBuff);
- for(int i = 0; i < nRet; i++)
- {
- if(szBuff[i] == L'\n')
- {
- SecureHelper::strncpyW_x(pDispInfo->szText, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE);
- break;
- }
- }
- #if (_WIN32_IE >= 0x0300)
- if(nRet > 0) // string was loaded, save it
- pDispInfo->uFlags |= TTF_DI_SETITEM;
- #endif // (_WIN32_IE >= 0x0300)
- }
-
- return 0;
- }
- #endif // !_WIN32_WCE
-
- // Implementation - chevron menu support
- #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
- bool PrepareChevronMenu(_ChevronMenuInfo& cmi)
- {
- // get rebar and toolbar
- REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO() };
- rbbi.fMask = RBBIM_CHILD;
- BOOL bRet = (BOOL)::SendMessage(cmi.lpnm->hdr.hwndFrom, RB_GETBANDINFO, cmi.lpnm->uBand, (LPARAM)&rbbi);
- ATLASSERT(bRet);
-
- // assume the band is a toolbar
- ATL::CWindow wnd = rbbi.hwndChild;
- int nCount = (int)wnd.SendMessage(TB_BUTTONCOUNT);
- if(nCount <= 0) // probably not a toolbar
- return false;
-
- // check if it's a command bar
- CMenuHandle menuCmdBar = (HMENU)wnd.SendMessage(CBRM_GETMENU);
- cmi.bCmdBar = (menuCmdBar.m_hMenu != NULL);
-
- // build a menu from hidden items
- CMenuHandle menu;
- bRet = menu.CreatePopupMenu();
- ATLASSERT(bRet);
- RECT rcClient = { 0 };
- bRet = wnd.GetClientRect(&rcClient);
- ATLASSERT(bRet);
- for(int i = 0; i < nCount; i++)
- {
- TBBUTTON tbb = { 0 };
- bRet = (BOOL)wnd.SendMessage(TB_GETBUTTON, i, (LPARAM)&tbb);
- ATLASSERT(bRet);
- // skip hidden buttons
- if((tbb.fsState & TBSTATE_HIDDEN) != 0)
- continue;
- RECT rcButton = { 0 };
- bRet = (BOOL)wnd.SendMessage(TB_GETITEMRECT, i, (LPARAM)&rcButton);
- ATLASSERT(bRet);
- bool bEnabled = ((tbb.fsState & TBSTATE_ENABLED) != 0);
- if(rcButton.right > rcClient.right)
- {
- if(tbb.fsStyle & BTNS_SEP)
- {
- if(menu.GetMenuItemCount() > 0)
- menu.AppendMenu(MF_SEPARATOR);
- }
- else if(cmi.bCmdBar)
- {
- const int cchBuff = 200;
- TCHAR szBuff[cchBuff] = { 0 };
- CMenuItemInfo mii;
- mii.fMask = MIIM_TYPE | MIIM_SUBMENU;
- mii.dwTypeData = szBuff;
- mii.cch = cchBuff;
- bRet = menuCmdBar.GetMenuItemInfo(i, TRUE, &mii);
- ATLASSERT(bRet);
- // Note: CmdBar currently supports only drop-down items
- ATLASSERT(::IsMenu(mii.hSubMenu));
- bRet = menu.AppendMenu(MF_STRING | MF_POPUP | (bEnabled ? MF_ENABLED : MF_GRAYED), (UINT_PTR)mii.hSubMenu, mii.dwTypeData);
- ATLASSERT(bRet);
- }
- else
- {
- // get button's text
- const int cchBuff = 200;
- TCHAR szBuff[cchBuff] = { 0 };
- LPTSTR lpstrText = szBuff;
- TBBUTTONINFO tbbi = { 0 };
- tbbi.cbSize = sizeof(TBBUTTONINFO);
- tbbi.dwMask = TBIF_TEXT;
- tbbi.pszText = szBuff;
- tbbi.cchText = cchBuff;
- if(wnd.SendMessage(TB_GETBUTTONINFO, tbb.idCommand, (LPARAM)&tbbi) == -1 || lstrlen(szBuff) == 0)
- {
- // no text for this button, try a resource string
- lpstrText = _T("");
- int nRet = ::LoadString(ModuleHelper::GetResourceInstance(), tbb.idCommand, szBuff, cchBuff);
- for(int n = 0; n < nRet; n++)
- {
- if(szBuff[n] == _T('\n'))
- {
- lpstrText = &szBuff[n + 1];
- break;
- }
- }
- }
- bRet = menu.AppendMenu(MF_STRING | (bEnabled ? MF_ENABLED : MF_GRAYED), tbb.idCommand, lpstrText);
- ATLASSERT(bRet);
- }
- }
- }
-
- if(menu.GetMenuItemCount() == 0) // no hidden buttons after all
- {
- menu.DestroyMenu();
- ::MessageBeep((UINT)-1);
- return false;
- }
-
- cmi.hMenu = menu;
- return true;
- }
-
- void DisplayChevronMenu(_ChevronMenuInfo& cmi)
- {
- #ifndef TPM_VERPOSANIMATION
- const UINT TPM_VERPOSANIMATION = 0x1000L; // Menu animation flag
- #endif
- // convert chevron rect to screen coordinates
- ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom;
- POINT pt = { cmi.lpnm->rc.left, cmi.lpnm->rc.bottom };
- wndFrom.MapWindowPoints(NULL, &pt, 1);
- RECT rc = cmi.lpnm->rc;
- wndFrom.MapWindowPoints(NULL, &rc);
- // set up flags and rect
- UINT uMenuFlags = TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | (!AtlIsOldWindows() ? TPM_VERPOSANIMATION : 0);
- TPMPARAMS TPMParams = { 0 };
- TPMParams.cbSize = sizeof(TPMPARAMS);
- TPMParams.rcExclude = rc;
- // check if this window has a command bar
- HWND hWndCmdBar = (HWND)::SendMessage(m_hWnd, CBRM_GETCMDBAR, 0, 0L);
- if(::IsWindow(hWndCmdBar))
- {
- CBRPOPUPMENU CBRPopupMenu = { sizeof(CBRPOPUPMENU), cmi.hMenu, uMenuFlags, pt.x, pt.y, &TPMParams };
- ::SendMessage(hWndCmdBar, CBRM_TRACKPOPUPMENU, 0, (LPARAM)&CBRPopupMenu);
- }
- else
- {
- CMenuHandle menu = cmi.hMenu;
- menu.TrackPopupMenuEx(uMenuFlags, pt.x, pt.y, m_hWnd, &TPMParams);
- }
- }
-
- void CleanupChevronMenu(_ChevronMenuInfo& cmi)
- {
- CMenuHandle menu = cmi.hMenu;
- // if menu is from a command bar, detach submenus so they are not destroyed
- if(cmi.bCmdBar)
- {
- for(int i = menu.GetMenuItemCount() - 1; i >=0; i--)
- menu.RemoveMenu(i, MF_BYPOSITION);
- }
- // destroy menu
- menu.DestroyMenu();
- // convert chevron rect to screen coordinates
- ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom;
- RECT rc = cmi.lpnm->rc;
- wndFrom.MapWindowPoints(NULL, &rc);
- // eat next message if click is on the same button
- MSG msg = { 0 };
- if(::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rc, msg.pt))
- ::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE);
- }
- #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
- };
-
-
- template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWinTraits>
- class ATL_NO_VTABLE CFrameWindowImpl : public CFrameWindowImplBase< TBase, TWinTraits >
- {
- public:
- HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
- DWORD dwStyle = 0, DWORD dwExStyle = 0,
- HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
- {
- ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
-
- dwStyle = T::GetWndStyle(dwStyle);
- dwExStyle = T::GetWndExStyle(dwExStyle);
-
- if(rect.m_lpRect == NULL)
- rect.m_lpRect = &TBase::rcDefault;
-
- return CFrameWindowImplBase< TBase, TWinTraits >::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam);
- }
-
- HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL)
- {
- const int cchName = 256;
- TCHAR szWindowName[cchName] = { 0 };
- #ifndef _WIN32_WCE
- ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
- HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
- #else // CE specific
- ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
-
- // This always needs to be NULL for Windows CE.
- // Frame Window menus have to go onto the CommandBar.
- // Use CreateSimpleCECommandBar
- HMENU hMenu = NULL;
- #endif // _WIN32_WCE
-
- T* pT = static_cast<T*>(this);
- HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
-
- if(hWnd != NULL)
- m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
-
- return hWnd;
- }
-
- BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
- {
- if(nResourceID == 0)
- nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
- #ifndef _WIN32_WCE
- ATLASSERT(!::IsWindow(m_hWndToolBar));
- m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID);
- return (m_hWndToolBar != NULL);
- #else // CE specific
- HWND hWnd= T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResourceID, TRUE, dwStyle, nID);
- return (hWnd != NULL);
- #endif // _WIN32_WCE
- }
-
- #ifdef _WIN32_WCE
- // CE specific variant that returns the handle of the toolbar
- HWND CreateSimpleCEToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
- {
- if(nResourceID == 0)
- nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
-
- return T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResourceID, TRUE, dwStyle, nID);
- }
- #endif // _WIN32_WCE
-
- // message map and handlers
- typedef CFrameWindowImplBase< TBase, TWinTraits > _baseClass;
-
- BEGIN_MSG_MAP(CFrameWindowImpl)
- MESSAGE_HANDLER(WM_SIZE, OnSize)
- #ifndef _ATL_NO_REBAR_SUPPORT
- #if (_WIN32_IE >= 0x0400)
- NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize)
- #endif // (_WIN32_IE >= 0x0400)
- #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
- NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed)
- #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
- #endif // !_ATL_NO_REBAR_SUPPORT
- CHAIN_MSG_MAP(_baseClass)
- END_MSG_MAP()
-
- LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
- {
- if(wParam != SIZE_MINIMIZED)
- {
- T* pT = static_cast<T*>(this);
- pT->UpdateLayout();
- }
- bHandled = FALSE;
- return 1;
- }
-
- #ifndef _ATL_NO_REBAR_SUPPORT
- #if (_WIN32_IE >= 0x0400)
- LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
- {
- T* pT = static_cast<T*>(this);
- pT->UpdateLayout(FALSE);
- return 0;
- }
- #endif // (_WIN32_IE >= 0x0400)
-
- #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
- LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
- {
- T* pT = static_cast<T*>(this);
- _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false };
- if(!pT->PrepareChevronMenu(cmi))
- {
- bHandled = FALSE;
- return 1;
- }
- // display a popup menu with hidden items
- pT->DisplayChevronMenu(cmi);
- // cleanup
- pT->CleanupChevronMenu(cmi);
- return 0;
- }
- #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
- #endif // !_ATL_NO_REBAR_SUPPORT
- };
-
-
- ///////////////////////////////////////////////////////////////////////////////
- // AtlCreateSimpleToolBar - helper for creating simple toolbars
-
- #ifndef _WIN32_WCE
-
- inline HWND AtlCreateSimpleToolBar(HWND hWndParent, UINT nResourceID, BOOL bInitialSeparator = FALSE,
- DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
- {
- return CFrameWindowImplBase<>::CreateSimpleToolBarCtrl(hWndParent, nResourceID, bInitialSeparator, dwStyle, nID);
- }
-
- #endif // !_WIN32_WCE
-
-
- ///////////////////////////////////////////////////////////////////////////////
- // CMDIWindow
-
- #ifndef _WIN32_WCE
-
- #ifndef _WTL_MDIWINDOWMENU_TEXT
- #define _WTL_MDIWINDOWMENU_TEXT _T("&Window")
- #endif
-
- class CMDIWindow : public ATL::CWindow
- {
- public:
- // Data members
- HWND m_hWndMDIClient;
- HMENU m_hMenu;
-
- // Constructors
- CMDIWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd), m_hWndMDIClient(NULL), m_hMenu(NULL)
- { }
-
- CMDIWindow& operator =(HWND hWnd)
- {
- m_hWnd = hWnd;
- return *this;
- }
-
- // Operations
- HWND MDIGetActive(BOOL* lpbMaximized = NULL)
- {
- ATLASSERT(::IsWindow(m_hWndMDIClient));
- return (HWND)::SendMessage(m_hWndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)lpbMaximized);
- }
-
- void MDIActivate(HWND hWndChildToActivate)
- {
- ATLASSERT(::IsWindow(m_hWndMDIClient));
- ATLASSERT(::IsWindow(hWndChildToActivate));
- ::SendMessage(m_hWndMDIClient, WM_MDIACTIVATE, (WPARAM)hWndChildToActivate, 0);
- }
-
- void MDINext(HWND hWndChild, BOOL bPrevious = FALSE)
- {
- ATLASSERT(::IsWindow(m_hWndMDIClient));
- ATLASSERT(hWndChild == NULL || ::IsWindow(hWndChild));
- ::SendMessage(m_hWndMDIClient, WM_MDINEXT, (WPARAM)hWndChild, (LPARAM)bPrevious);
- }
-
- void MDIMaximize(HWND hWndChildToMaximize)
- {
- ATLASSERT(::IsWindow(m_hWndMDIClient));
- ATLASSERT(::IsWindow(hWndChildToMaximize));
- ::SendMessage(m_hWndMDIClient, WM_MDIMAXIMIZE, (WPARAM)hWndChildToMaximize, 0);
- }
-
- void MDIRestore(HWND hWndChildToRestore)
- {
- ATLASSERT(::IsWindow(m_hWndMDIClient));
- ATLASSERT(::IsWindow(hWndChildToRestore));
- ::SendMessage(m_hWndMDIClient, WM_MDIRESTORE, (WPARAM)hWndChildToRestore, 0);
- }
-
- void MDIDestroy(HWND hWndChildToDestroy)
- {
- ATLASSERT(::IsWindow(m_hWndMDIClient));
- ATLASSERT(::IsWindow(hWndChildToDestroy));
- ::SendMessage(m_hWndMDIClient, WM_MDIDESTROY, (WPARAM)hWndChildToDestroy, 0);
- }
-
- BOOL MDICascade(UINT uFlags = 0)
- {
- ATLASSERT(::IsWindow(m_hWndMDIClient));
- return (BOOL)::SendMessage(m_hWndMDIClient, WM_MDICASCADE, (WPARAM)uFlags, 0);
- }
-
- BOOL MDITile(UINT uFlags = MDITILE_HORIZONTAL)
- {
- ATLASSERT(::IsWindow(m_hWndMDIClient));
- return (BOOL)::SendMessage(m_hWndMDIClient, WM_MDITILE, (WPARAM)uFlags, 0);
- }
-
- void MDIIconArrange()
- {
- ATLASSERT(::IsWindow(m_hWndMDIClient));
- ::SendMessage(m_hWndMDIClient, WM_MDIICONARRANGE, 0, 0);
- }
-
- HMENU MDISetMenu(HMENU hMenuFrame, HMENU hMenuWindow)
- {
- ATLASSERT(::IsWindow(m_hWndMDIClient));
- return (HMENU)::SendMessage(m_hWndMDIClient, WM_MDISETMENU, (WPARAM)hMenuFrame, (LPARAM)hMenuWindow);
- }
-
- HMENU MDIRefreshMenu()
- {
- ATLASSERT(::IsWindow(m_hWndMDIClient));
- return (HMENU)::SendMessage(m_hWndMDIClient, WM_MDIREFRESHMENU, 0, 0);
- }
-
- // Additional operations
- static HMENU GetStandardWindowMenu(HMENU hMenu)
- {
- int nCount = ::GetMenuItemCount(hMenu);
- if(nCount == -1)
- return NULL;
- int nLen = ::GetMenuString(hMenu, nCount - 2, NULL, 0, MF_BYPOSITION);
- if(nLen == 0)
- return NULL;
- CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
- LPTSTR lpszText = buff.Allocate(nLen + 1);
- if(lpszText == NULL)
- return NULL;
- if(::GetMenuString(hMenu, nCount - 2, lpszText, nLen + 1, MF_BYPOSITION) != nLen)
- return NULL;
- if(lstrcmp(lpszText, _WTL_MDIWINDOWMENU_TEXT) != 0)
- return NULL;
- return ::GetSubMenu(hMenu, nCount - 2);
- }
-
- void SetMDIFrameMenu()
- {
- HMENU hWindowMenu = GetStandardWindowMenu(m_hMenu);
- MDISetMenu(m_hMenu, hWindowMenu);
- MDIRefreshMenu();
- ::DrawMenuBar(GetMDIFrame());
- }
-
- HWND GetMDIFrame() const
- {
- return ::GetParent(m_hWndMDIClient);
- }
- };
-
- #endif // !_WIN32_WCE
-
-
- ///////////////////////////////////////////////////////////////////////////////
- // CMDIFrameWindowImpl
-
- #ifndef _WIN32_WCE
-
- // MDI child command chaining macro (only for MDI frame windows)
- #define CHAIN_MDI_CHILD_COMMANDS() \
- if(uMsg == WM_COMMAND) \
- { \
- HWND hWndChild = MDIGetActive(); \
- if(hWndChild != NULL) \
- ::SendMessage(hWndChild, uMsg, wParam, lParam); \
- }
-
- template <class T, class TBase = CMDIWindow, class TWinTraits = ATL::CFrameWinTraits>
- class ATL_NO_VTABLE CMDIFrameWindowImpl : public CFrameWindowImplBase<TBase, TWinTraits >
- {
- public:
- HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
- DWORD dwStyle = 0, DWORD dwExStyle = 0,
- HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
- {
- m_hMenu = hMenu;
- ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
-
- dwStyle = T::GetWndStyle(dwStyle);
- dwExStyle = T::GetWndExStyle(dwExStyle);
-
- if(rect.m_lpRect == NULL)
- rect.m_lpRect = &TBase::rcDefault;
-
- return CFrameWindowImplBase<TBase, TWinTraits >::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam);
- }
-
- HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL)
- {
- const int cchName = 256;
- TCHAR szWindowName[cchName] = { 0 };
- ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
- HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
-
- T* pT = static_cast<T*>(this);
- HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
-
- if(hWnd != NULL)
- m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
-
- return hWnd;
- }
-
- BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
- {
- ATLASSERT(!::IsWindow(m_hWndToolBar));
- if(nResourceID == 0)
- nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
- m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID);
- return (m_hWndToolBar != NULL);
- }
-
- virtual WNDPROC GetWindowProc()
- {
- return MDIFrameWindowProc;
- }
-
- static LRESULT CALLBACK MDIFrameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- CMDIFrameWindowImpl< T, TBase, TWinTraits >* pThis = (CMDIFrameWindowImpl< T, TBase, TWinTraits >*)hWnd;
- // set a ptr to this message and save the old value
- #if (_ATL_VER >= 0x0700)
- ATL::_ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
- const ATL::_ATL_MSG* pOldMsg = pThis->m_pCurrentMsg;
- #else // !(_ATL_VER >= 0x0700)
- MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
- const MSG* pOldMsg = pThis->m_pCurrentMsg;
- #endif // !(_ATL_VER >= 0x0700)
- pThis->m_pCurrentMsg = &msg;
- // pass to the message map to process
- LRESULT lRes = 0;
- BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
- // restore saved value for the current message
- ATLASSERT(pThis->m_pCurrentMsg == &msg);
- pThis->m_pCurrentMsg = pOldMsg;
- // do the default processing if message was not handled
- if(!bRet)
- {
- if(uMsg != WM_NCDESTROY)
- lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
- else
- {
- // unsubclass, if needed
- LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC);
- lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
- if(pThis->m_pfnSuperWindowProc != ::DefWindowProc && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc)
- ::SetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
- #if (_ATL_VER >= 0x0700)
- // mark window as destryed
- pThis->m_dwState |= WINSTATE_DESTROYED;
- #else // !(_ATL_VER >= 0x0700)
- // clear out window handle
- HWND hWnd = pThis->m_hWnd;
- pThis->m_hWnd = NULL;
- // clean up after window is destroyed
- pThis->OnFinalMessage(hWnd);
- #endif // !(_ATL_VER >= 0x0700)
- }
- }
- #if (_ATL_VER >= 0x0700)
- if(pThis->m_dwState & WINSTATE_DESTROYED && pThis->m_pCurrentMsg == NULL)
- {
- // clear out window handle
- HWND hWnd = pThis->m_hWnd;
- pThis->m_hWnd = NULL;
- pThis->m_dwState &= ~WINSTATE_DESTROYED;
- // clean up after window is destroyed
- pThis->OnFinalMessage(hWnd);
- }
- #endif // (_ATL_VER >= 0x0700)
- return lRes;
- }
-
- // Overriden to call DefWindowProc which uses DefFrameProc
- LRESULT DefWindowProc()
- {
- const MSG* pMsg = m_pCurrentMsg;
- LRESULT lRes = 0;
- if (pMsg != NULL)
- lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
- return lRes;
- }
-
- LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- return ::DefFrameProc(m_hWnd, m_hWndMDIClient, uMsg, wParam, lParam);
- }
-
- BOOL PreTranslateMessage(MSG* pMsg)
- {
- if(CFrameWindowImplBase<TBase, TWinTraits>::PreTranslateMessage(pMsg))
- return TRUE;
- return ::TranslateMDISysAccel(m_hWndMDIClient, pMsg);
- }
-
- HWND CreateMDIClient(HMENU hWindowMenu = NULL, UINT nID = ATL_IDW_CLIENT, UINT nFirstChildID = ATL_IDM_FIRST_MDICHILD)
- {
- DWORD dwStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | MDIS_ALLCHILDSTYLES;
- DWORD dwExStyle = WS_EX_CLIENTEDGE;
-
- CLIENTCREATESTRUCT ccs = { 0 };
- ccs.hWindowMenu = hWindowMenu;
- ccs.idFirstChild = nFirstChildID;
-
- if((GetStyle() & (WS_HSCROLL | WS_VSCROLL)) != 0)
- {
- // parent MDI frame's scroll styles move to the MDICLIENT
- dwStyl…