⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tabbedmdi.h

📁 These listed libraries are written in WTL. But it s really hard to mix both MFC & WTL together. Obvi
💻 H
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////
// TabbedMDI.h - Classes that help implement a "Tabbed MDI" interface.
//
// Classes:
//   CTabbedMDIFrameWindowImpl - 
//      Instead of having CMainFrame inherit from
//      CMDIFrameWindowImpl, you can have it inherit from
//      CTabbedMDIFrameWindowImpl. For an out-of-the box WTL MDI
//      application, there are 3 instances of CMDIFrameWindowImpl
//      to replace with CTabbedMDIFrameWindowImpl.
//   CTabbedMDIChildWindowImpl - 
//      If you want your MDI child window to have a corresponding
//      tab in the MDI tab window, inherit from this class instead
//      of from CMDIChildWindowImpl.
//   CTabbedMDIClient - 
//      The CTabbedMDIFrameWindowImpl contains CTabbedMDIClient,
//      which subclasses the "MDI Client" window
//      (from the OS, that manages the MDI child windows).
//      It handles sizing/positioning the tab window,
//      calling the appropriate Display, Remove, UpdateText
//      for the tabs with the HWND of the active child,
//      etc.  You can use CTabbedMDIClient without using
//      CTabbedMDIFrameWindowImpl. To do so, simply call
//      SetTabOwnerParent(m_hWnd) then SubclassWindow(m_hWndMDIClient)
//      on a CTabbedMDIClient member variable after calling
//      CreateMDIClient in your main frame class.
//   CMDITabOwner -
//      The MDITabOwner is the parent of the actual tab window
//      (such as CDotNetTabCtrl), and sibling to the "MDI Client" window.
//      The tab owner tells the MDI child when to display a context
//      menu for the tab (the default menu is the window's system menu).
//      The tab owner changes the active MDI child when the
//      active tab changes.  It also does the real work of
//      hiding and showing the tabs.  It also handles adding,
//      removing, and renaming tabs based on an HWND.
//   CTabbedMDICommandBarCtrl/CTabbedMDICommandBarCtrlImpl -
//      In your MDI application, instead of using CMDICommandBarCtrl,
//      use CTabbedMDICommandBarCtrl.  It addresses a couple of bugs
//      in WTL 7.0's CMDICommandBarCtrl, and allows you to enable
//      or disable whether you want to see the document icon
//      and min/max/close button in the command bar when the
//      child is maximized.  To add additional functionality,
//      derive your own class from CTabbedMDICommandBarCtrlImpl.
//      
//     
//
// Written by Daniel Bowen (dbowen@es.com)
// Copyright (c) 2002-2005 Daniel Bowen.
//
// Depends on CustomTabCtrl.h originally by Bjarke Viksoe (bjarke@viksoe.dk)
//  with the modifications by Daniel Bowen
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever.
//
// If you find bugs, have suggestions for improvements, etc.,
// please contact the author.
//
// History (Date/Author/Description):
// ----------------------------------
//
// 2005/07/13: Daniel Bowen
// - Namespace qualify the use of more ATL and WTL classes.
// - CTabbedMDIFrameWindowImpl:
//   * Add GetMDITabCtrl
//
// 2005/04/12: Daniel Bowen
// - CTabbedMDIClient::OnNcPaint - 
//   * CDC dc(this->GetWindowDC());
//       should be
//     CWindowDC dc(this->m_hWnd);
//
// 2005/04/08: Daniel Bowen
// - Generalize support for having the tab control automatically hidden
//   if the number of tabs is below a certain count.
// - CMDITabOwnerImpl -
//   * Move KeepTabsHidden support into base class CCustomTabOwnerImpl
//   * Move HideMDITabsWhenMDIChildNotMaximized to CMDITabOwnerImpl and have
//     CTabbedMDIClient forward it's call of the same to the tab owner.
//   * Change old "OnAddFirstTab" and "OnRemoveLastTab" to work with
//     new refactored support in CCustomTabOwnerImpl.  It's now
//     OnAddTab and OnRemoveTab with the help of ShowTabControl and
//     HideTabControl.  The work that used to be done
//     in OnAddFirstTab and OnRemoveLastTab is now done in
//     ForceShowMDITabControl and ForceHideMDITabControl.
//   * Add ShowTabControlIfChildMaximized and HideTabControlIfChildNotMaximized
//     that CTabbedMDIClient calls (since this class now tracks
//     HideMDITabsWhenMDIChildNotMaximized)
// - CTabbedMDIClient -
//   * Move HideMDITabsWhenMDIChildNotMaximized to CMDITabOwnerImpl and have
//     CTabbedMDIClient forward it's call of the same to the tab owner.
//
// 2005/03/14: Daniel Bowen
// - Fix warnings when compiling for 64-bit.
//
// 2005/02/03: Daniel Bowen
// - Move registered window messages into TabbedMDIMessages.h
//
// 2004/11/29: Daniel Bowen
// - Update all WM_NOTIFY handlers to check that the notification is
//   from the tab control (and not from a sibling like a list view control)
//
// 2004/06/28: Daniel Bowen
// - CMDITabOwnerImpl -
//   * Fix GetTabStyles to return DWORD instead of bool
// - CTabbedMDIChildWindowImpl -
//   * OnShowTabContextMenu - Add warning in Debug builds if using non SC_* command.
//     To use use non SC_* commands, you should override handling
//      UWM_MDICHILDSHOWTABCONTEXTMENU
//     in a derived class, and do your own context menu there.
//     See the "TabDemo" sample for an example.
// - Clean up warnings on level 4
//
// 2004/05/14: Daniel Bowen
// - CMDITabOwnerImpl - 
//   * Update OnClick handling so it only sets focus to the tab view
//     if the selected tab is being clicked. Without this update,
//     other code that tries to minimize flickering when switching
//     the active view doesn't get called.
// - CTabbedMDIClient
//   * Fix bug in SaveModified that checks incoming argument for NULL
//
// 2004/04/29: Daniel Bowen
// - Require WTL version 7.1 or later (because of WTL's CMDICommandBarCtrlImpl)
// - New and changed registered messages for tabbed MDI children:
//   * UWM_MDICHILDISMODIFIED - Asks whether the document(s) referenced by a 
//     tabbed MDI child has been modified, and if so, the LPARAM has an
//     ITabbedMDIChildModifiedItem* with which to fill out information.
//     Return TRUE if there are one or more modified documents for the child.
//   * UWM_MDICHILDSAVEMODIFIED (change meaning slightly) - Tells the tabbed MDI
//     child to save any modifications without asking.  The LPARAM is an
//     ITabbedMDIChildModifiedItem* with additional information.  Before, this message
//     was used to ask about saving modifications, then saving if the user chose to.
//     The asking about modifications is now consolidated in "SaveAllModified"
//     (or by doing FindModified, CSaveModifiedItemsDialog, SaveModified).
//   * UWM_MDICHILDCLOSEWITHNOPROMPT - Closes the tabbed MDI child bypassing WM_CLOSE
//     (so that the user isn't prompted to save modifications - for when they've
//     already been asked).
// - CTabbedMDIClient
//   * New "HideMDITabsWhenMDIChildNotMaximized".  If you call this
//     with TRUE, then the MDI tabs are shown when the MDI children
//     are maximized, and hidden when they are not maximized.
//   * Change "SaveAllModified".  It can be used to implement "save all"
//     that doesn't prompt, or it can be used to prompt about saving any
//     modified documents using a dialog with a checkbox list for modified items
//     (which only works with tabbed MDI children).
//   * FindModified - Asks all tabbed MDI children whether they have been
//     modified, and uses ITabbedMDIChildModifiedList and ITabbedMDIChildModifiedItem
//     for extended information.
//   * SaveModified - Iterates items in a ITabbedMDIChildModifiedList and
//     sends UWM_MDICHILDSAVEMODIFIED to save modifications. If an item has
//     sub-items, the "top-level" item is responsible for ensuring that
//     modifications are saved.
//   * CloseAll - Close all MDI child windows.  If bPreferNoPrompt is true,
//     try sending UWM_MDICHILDCLOSEWITHNOPROMPT first to the window, so that
//      the child is closed and the user is not prompted about any modifications.
//     Otherwise send WM_SYSCOMMAND with SC_CLOSE, which sends WM_CLOSE.
// - CMDITabOwnerImpl
//   * Have the MDI tab styles default to using the new style
//     CTCS_DRAGREARRANGE
//   * Respond to NM_CLICK, CTCN_ACCEPTITEMDRAG and CTCN_CANCELITEMDRAG
//     from the tab control, and set focus to the tab item's view
//
// 2003/12/16: Daniel Bowen
// - CTabbedMDICommandBarCtrlImpl
//   * Update OnMDISetMenu to match CMDICommandBarCtrlImpl::OnMDISetMenu in WTL 7.1
//   * Update RefreshMaximizedState to match corresponding code in
//     CMDICommandBarCtrlImpl::OnAllHookMessages in WTL 7.1
//   * Have RefreshMaximizedState be overrideable (call through pT->)
//   * Have RefreshMaximizedState's 2nd parameter indicate whether the document
//     icon has changed, instead of whether the child has changed
//     (to match what WTL 7.1 is doing in OnAllHookMessages)
///  * NOTE: There is a problem in WTL 7.1 OnAllHookMessages that
//     CTabbedMDICommandBarCtrlImpl fixes.  See
//     http://groups.yahoo.com/group/wtl/message/7627
//     for a description of the fix.  Future versions of WTL should
//     also have this fix.
//
// 2003/08/11: Daniel Bowen
// - CMDITabOwner:
//   * Add new "KeepTabsHidden" method.
//   * Have the old CMDITabOwner be CMDITabOwnerImpl with new template parameter
//     for most derived class so that others can derive from it and
//     have things work right.  CMDITabOwner now is very simple and
//     just inherits from CMDITabOwnerImpl
// - Use "LongToHandle" with return value from GetClassLong
//
// 2003/06/27: Daniel Bowen
// - CMDITabOwner:
//   * Use typedefs for thisClass, baseClass, customTabOwnerClass
//   * Replace
//      DECLARE_WND_CLASS(_T("MdiTabOwner"))
//     with
//      DECLARE_WND_CLASS_EX(_T("MdiTabOwner"), 0, COLOR_APPWORKSPACE)
//     (gets rid of CS_DBLCLKS, CS_HREDRAW and CS_VREDRAW, sets background brush)
//   * Have OnAddFirstTab and OnRemoveLastTab call base class versions
//     (in case we ever do anything interesting there)
// - Check failure of window creation (DefWindowProc when handling WM_CREATE)
//   and return immediately if it failed.
//
// 2003/06/03: Daniel Bowen
// - Fix compile errors for VC 7.1
//
// 2003/02/27: Daniel Bowen
// - Use _U_RECT instead of WTL::_U_RECT.
//   For VC7, this means you must #define _WTL_NO_UNION_CLASSES
//   before including the WTL header files, or you will
//   get compile errors (the ATL7 union classes are defined
//   in atlwin.h).
//
// 2002/12/11: Daniel Bowen
// - New UWM_MDICHILDSAVEMODIFIED message sent to MDI child frames.
//   The child frame receiving this should see if the "document"
//   has been modified, and needs to be saved (usually with a 
//   yes/no/cancel message box).  If the user chooses to cancel,
//   return non-zero from the UWM_MDICHILDSAVEMODIFIED handler.
// - CTabbedMDIClient -
//   * SaveAllModified - Iterates the MDI child windows, and
//      sends UWM_MDICHILDSAVEMODIFIED. If a child returns non-zero,
//      the iteration stops.  You can also specify whether to
//      close the child window after sending UWM_MDICHILDSAVEMODIFIED.
//   * CloseAll - Close All MDI child windows.  When handling WM_CLOSE,
//      the MDI child window should *not* have a "Cancel" option
//      if prompting to save a modified document.
//
// 2002/11/27: Daniel Bowen
// - CTabbedMDIChildWindowImpl -
//   * When handling WM_MOUSEACTIVATE in CTabbedMDIChildWindowImpl,
//     let the message get to the top window before possibly doing
//     MDIActivate (more like the MFC code in CMDIChildWnd::OnMouseActivate)
//
// 2002/11/21: Daniel Bowen
// - CMDITabOwner - 
//   * ModifyTabStyles for use before CMDITabOwner is created as a window
// - CTabbedMDIClient -
//   * Expose SetDrawFlat and GetDrawFlat
//   * Updates so that drawing flat draws correctly
// - CTabbedMDIChildWindowImpl - 
//   * Handle WM_MOUSEACTIVATE, and call MDIActivate if
//     MDI child is not already active.  This solves the problem
//     where you have a dialog window as the view of the MDI child,
//     and clicking on a child control (edit box, etc.) doesn't
//     give focus or activate the MDI child (or activate the app
//     if its not active).  This code will ideally make its
//     way into future versions of WTL.
//
// 2002/09/25: Daniel Bowen
// - CTabbedMDICommandBarCtrl -
//   * Break out CTabbedMDICommandBarCtrl into CTabbedMDICommandBarCtrlImpl
//     and CTabbedMDICommandBarCtrl (just like CMDICommandBarCtrlImpl
//     and CMDICommandBarCtrl).
//     You can derive from CTabbedMDICommandBarCtrlImpl
//     if you would like to extend functionality (such as providing
//     your own handling of WM_MDISETMENU).  See the commented out
//     sample class after CTabbedMDICommandBarCtrl.
// - CMDITabOwner -
//   * Expose "SetTabStyles" and "GetTabStyles" so that you can change
//     the tab related styles to something different than the default
// - UWM_MDI... messages -
//   * The TabbedMDI related classes use a handful of custom window
//     messages.  These messages are guaranteed to be unique across
//     all windows for a particular windows session by using
//     RegisterWindowMessage
//
//     Initially, these message IDs were declared as static variables
//     and initialized here in the header.
//     However, that gave them "internal linkeage".  Essentially,
//     this meant that there were multiple copies of these variables.
//     In Visual C++ 6, there was also a bug that caused the variables
//     not to be initialized properly in release mode. So the class
//     CTabbedMDIChildWindowImpl ensured their initialization in its
//     constructor.  The problem was, only the version of the variables
//     in the same translation unit got initialized by doing it this way.
//
//     These variables are now declared using __declspec(selectany)
//     so that there will not be multiple copies.  RegisterWindowMessage
//     for each message ID is now called in the constructor of the
//     struct "RegisterTabbedMDIMessages". If you are using _ATL_MIN_CRT
//     or define _TABBEDMDI_MESSAGES_EXTERN_REGISTER, then you must
//     have an instance of the "RegisterTabbedMDIMessages" struct in
//     one .cpp file.  Otherwise, a global instance of the struct will
//     be declared in this header file (whose constructor will be called
//     by the CRT at load time).  If you are not referencing
//     TabbedMDI.h in stdafx.h, and have multiple translation units
//     including it, then you'll need to do it the 
//     _TABBEDMDI_MESSAGES_EXTERN_REGISTER way.  Also, if you do
//     use _ATL_MIN_CRT, you will get a warning unless you define
//     _TABBEDMDI_MESSAGES_NO_WARN_ATL_MIN_CRT
//
// 2002/08/26: Daniel Bowen
// - CTabbedMDIClient -
//   * Add new template parameter "TTabOwner" to allow easily
//     changing the tab owner class used
//
// 2002/06/26: Daniel Bowen
// - CTabbedMDIFrameWindowImpl - Expose "TClient" and "TTabCtrl".
// - CMDITabOwner - Expose "TTabCtrl".
// - CTabbedMDIClient -
//   * Expose "TTabCtrl"
//   * New method "GetTabOwner" to get a reference to the C++ class
//     instance implementing the MDI tab owner window.
//   * New method "UseMDIChildIcon" to specify that you want the MDI
//     tabs to include the document icon for the MDI child on the
//     corresponding tab
// 
// 2002/06/12: Daniel Bowen
// - Publish codeproject article.  For history prior
//   to the release of the article, please see the article
//   and the section "Note to previous users"

#ifndef __WTL_TABBED_MDI_H__
#define __WTL_TABBED_MDI_H__

#pragma once

#ifndef __cplusplus
	#error Tabbed MDI requires C++ compilation (use a .cpp suffix)
#endif

#ifndef __ATLAPP_H__
	#error TabbedMDI.h requires atlapp.h to be included first
#endif

#ifndef __ATLWIN_H__
	#error TabbedMDI.h requires atlwin.h to be included first
#endif

#ifndef __ATLFRAME_H__
	#error TabbedFrame.h requires atlframe.h to be included first
#endif

#ifndef __ATLCTRLW_H__
	#error TabbedFrame.h requires atlctrlw.h to be included first
#endif

#if _WTL_VER < 0x0710
	#error TabbedMDI.h requires WTL 7.1 or higher
#endif

#ifndef __CUSTOMTABCTRL_H__
#include "CustomTabCtrl.h"
#endif

#ifndef __WTL_TABBED_FRAME_H__
#include "TabbedFrame.h"
#endif

#ifndef __WTL_TABBED_MDI_MESSAGES_H__
#include "TabbedMDIMessages.h"
#endif


/////////////////////////////////////////////////////////////////////////////
//
// CTabbedMDIFrameWindowImpl
//
/////////////////////////////////////////////////////////////////////////////

template <
	class T,
	class TClient = CTabbedMDIClient< CDotNetTabCtrl<CTabViewTabItem> >,
	class TBase = WTL::CMDIWindow,
	class TWinTraits = ATL::CFrameWinTraits>
class ATL_NO_VTABLE CTabbedMDIFrameWindowImpl :
	public WTL::CMDIFrameWindowImpl<T, TBase, TWinTraits >
{
public:
	// Expose the type of MDI client
	typedef typename TClient TClient;
	// Expose the type of tab control
	typedef typename TClient::TTabCtrl TTabCtrl;
	
// Member variables
protected:
	TClient m_tabbedClient;

// Methods
public:
	// Either call the normal "CreateMDIClient"

	HWND CreateMDIClient(HMENU hWindowMenu = NULL, UINT nID = ATL_IDW_CLIENT, UINT nFirstChildID = ATL_IDM_FIRST_MDICHILD)
	{
		HWND hWndClient = baseClass::CreateMDIClient(hWindowMenu, nID, nFirstChildID);

		this->SubclassMDIClient();

		return hWndClient;
	}

	// Or, after creating the client, call SubclassMDIClient
	BOOL SubclassMDIClient()
	{
		ATLASSERT(m_hWndMDIClient && ::IsWindow(m_hWndMDIClient));

		return m_tabbedClient.SubclassWindow(m_hWndMDIClient);
	}

	void SetTabOwnerParent(HWND hWndTabOwnerParent)
	{
		m_tabbedClient.SetTabOwnerParent(hWndTabOwnerParent);
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -