1. 程式人生 > >如何去除MFC視窗的自動記憶功能 (如去除工具欄,選單欄上次執行程式自動儲存的內容)

如何去除MFC視窗的自動記憶功能 (如去除工具欄,選單欄上次執行程式自動儲存的內容)

BCG登錄檔清除:
第一次在CXXXApp::ExitInstance() 加入CleanState(),
執行一次
接著註釋掉,再在OnInitInstance加入m_bSaveState=FALSE
估計在BCG控制元件要寫登錄檔的時候,它自己的寫入登錄檔函式會判斷m_bSaveState

1.VC2008集成了BCGControlBar的相關功能,用wizard生成的話如果選與BCGControlBar有關的效能,如預定面板,則應用程式是從CWinAppEx派生,再加CBCGPWorkspace似乎不行。


2.BCG 為了方便程式設計師,在登錄檔中儲存了視窗的大小、位置等資訊,包括工具欄的相應資訊。這樣減少了程式設計師儲存和恢復使用者上次使用過的介面的重複勞動。但也會造成改變選單之類出現無反應的現象,讓人摸不著頭腦。可以採用的一個方法是,刪除 BCG 為你儲存的登錄檔鍵:
HKEY_CURRENT_USER/Software/[your corporation]/[your application]/Workspace
裡面 your corporation 是指在 app 類裡面 SetRegistryKey 指定的路徑;your application 就是你的應用程式名。
把這個刪掉之後,還是用你最上面的程式碼,執行。OK!

更方便的是InitInstance裡設m_bSaveState=FALSE;

如果已經有註冊內容了再加一句CleanState();

程式成型後再加上。


3.應用面板的過程
(1)找一個BCG的例子,將選單與面板相關的項複製貼上到你的選單下,ID值是連續的。

(2)CMainFrame的標頭檔案中
#define CFrameWnd CBCGPFrameWnd//類定義前。這樣可以省很多替換工作哦
UINT m_nAppLook;//指示應用哪個面板
CBCGPMenuBar m_wndMenuBar;
//手動加入訊息響應:
afx_msg void OnAppLook(UINT id);
afx_msg void OnUpdateAppLook(CCmdUI* pCmdUI);

(3)CMainFrame的Cpp檔案
//訊息對映增加
ON_COMMAND_RANGE(ID_VIEW_APPLOOK_2000, ID_VIEW_APPLOOK_VS2008, OnAppLook) //這是範圍的響應,所以ID要連續
ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_2000, ID_VIEW_APPLOOK_VS2008, OnUpdateAppLook)
//初始化函式
m_nAppLook = theApp.GetInt (_T("ApplicationLook"), ID_VIEW_APPLOOK_2003);//初始的樣子
//OnCreate
OnAppLook (m_nAppLook);

if (!m_wndMenuBar.Create (this))
{
TRACE0("Failed to create menubar/n");
return -1; // fail to create
}

m_wndMenuBar.SetBarStyle(m_wndMenuBar.GetBarStyle() | CBRS_SIZE_DYNAMIC);

m_wndMenuBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
EnableAutoHideBars(CBRS_ALIGN_ANY);
DockControlBar(&m_wndMenuBar); //可浮動

//直接把以下兩個函式拷貝上去就OK了。
void CMainFrame::OnAppLook(UINT id)
{
CBCGPDockManager::SetDockMode (BCGP_DT_SMART);

m_nAppLook = id;

switch (m_nAppLook)
{
case ID_VIEW_APPLOOK_2000:
// enable Office 2000 look:
CBCGPVisualManager::SetDefaultManager (RUNTIME_CLASS (CBCGPVisualManager));
break;

case ID_VIEW_APPLOOK_XP:
// enable Office XP look:
CBCGPVisualManager::SetDefaultManager (RUNTIME_CLASS (CBCGPVisualManagerXP));
break;

case ID_VIEW_APPLOOK_WIN_XP:
// enable Windows XP look (in other OS Office XP look will be used):
CBCGPWinXPVisualManager::m_b3DTabsXPTheme = TRUE;
CBCGPVisualManager::SetDefaultManager (RUNTIME_CLASS (CBCGPWinXPVisualManager));
break;

case ID_VIEW_APPLOOK_2003:
// enable Office 2003 look:
CBCGPVisualManager::SetDefaultManager (RUNTIME_CLASS (CBCGPVisualManager2003));
CBCGPDockManager::SetDockMode (BCGP_DT_SMART);
break;

case ID_VIEW_APPLOOK_VS2005:
// enable VS 2005 look:
CBCGPVisualManager::SetDefaultManager (RUNTIME_CLASS (CBCGPVisualManagerVS2005));
CBCGPVisualManager::GetInstance ();
CBCGPDockManager::SetDockMode (BCGP_DT_SMART);
break;

case ID_VIEW_APPLOOK_VS2008:
// enable VS 2008 look:
CBCGPVisualManager::SetDefaultManager (RUNTIME_CLASS (CBCGPVisualManagerVS2008));
CBCGPVisualManager::GetInstance ();
CBCGPDockManager::SetDockMode (BCGP_DT_SMART);
break;

case ID_VIEW_APPLOOK_2007_1:
// enable Office 2007 look:
CBCGPVisualManager2007::SetStyle (CBCGPVisualManager2007::VS2007_LunaBlue);
CBCGPVisualManager::SetDefaultManager (RUNTIME_CLASS (CBCGPVisualManager2007));
CBCGPDockManager::SetDockMode (BCGP_DT_SMART);
break;

case ID_VIEW_APPLOOK_2007_2:
// enable Office 2007 look:
CBCGPVisualManager2007::SetStyle (CBCGPVisualManager2007::VS2007_ObsidianBlack);
CBCGPVisualManager::SetDefaultManager (RUNTIME_CLASS (CBCGPVisualManager2007));
CBCGPDockManager::SetDockMode (BCGP_DT_SMART);
break;

case ID_VIEW_APPLOOK_2007_3:
// enable Office 2007 look:
CBCGPVisualManager2007::SetStyle (CBCGPVisualManager2007::VS2007_Aqua);
CBCGPVisualManager::SetDefaultManager (RUNTIME_CLASS (CBCGPVisualManager2007));
CBCGPDockManager::SetDockMode (BCGP_DT_SMART);
break;

case ID_VIEW_APPLOOK_2007_4:
// enable Office 2007 look:
CBCGPVisualManager2007::SetStyle (CBCGPVisualManager2007::VS2007_Silver);
CBCGPVisualManager::SetDefaultManager (RUNTIME_CLASS (CBCGPVisualManager2007));
CBCGPDockManager::SetDockMode (BCGP_DT_SMART);
break;

default:
ASSERT (FALSE);
}

CBCGPDockManager* pDockManager = GetDockManager ();
if (pDockManager != NULL)
{
ASSERT_VALID (pDockManager);
pDockManager->AdjustBarFrames ();
}

RecalcLayout ();
RedrawWindow (NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);

theApp.WriteInt (_T("ApplicationLook"), m_nAppLook);
}


void CMainFrame::OnUpdateAppLook(CCmdUI* pCmdUI)
{
pCmdUI->SetRadio (m_nAppLook == pCmdUI->m_nID);
}

4.上下文選單

(1)當然是新建一個需要的上下文選單

(2)應用程式類的標頭檔案下

virtual void PreLoadState ();

Cpp檔案

void C***App::PreLoadState ()
{

GetContextMenuManager()->AddMenu (_T("My menu"), IDR_CONTEXT_MENU);//IDR_CONTEXT_MENU是選單的ID

// TODO: add another context menus here
}

(3)響應上下文選單的檢視類中增加對上下文選單訊息的響應

void C***View::OnContextMenu(CWnd* , CPoint point)
{
theApp.ShowPopupMenu (IDR_CONTEXT_MENU, point, this);
// TODO: 在此處新增訊息處理程式程式碼
}

2.

BCG例子BCGPExplorer:

1.BCG的選單、工具欄、動畫圖示和位址列

這是BCG的主要特色,也比較繁瑣。

(1)如果要支援自定義工具。

首先在String表定義入口ID:ID_TOOLS_ENTRY,與某選單項關聯。然後定義連續的ID,如ID_USER_TOOL1、ID_USER_TOOL2......。

在App下增加 EnableUserTools (ID_TOOLS_ENTRY, ID_USER_TOOL1, ID_USER_TOOL10);

(2)主要是修改CMainFrame

標頭檔案宣告

CBCGPMenuBar m_wndMenuBar;
CBCGPStatusBar m_wndStatusBar;
CBCGPToolBar m_wndToolBar;
CBCGPReBar m_wndReBar; //選單、工具欄、位址列的容器
CBCGPAnimCtrl m_wndAnimate;//動畫控制元件
CComboBoxEx m_wndAddress;//位址列

增加響應自定義工具的訊息函式OnViewCustomize

手動新增訊息響應

afx_msg LRESULT OnToolbarReset(WPARAM,LPARAM);
afx_msg LRESULT OnToolbarContextMenu(WPARAM,LPARAM);

虛擬函式virtual BOOL OnShowPopupMenu (CBCGPPopupMenu* pMenuPopup);

Cpp檔案

ON_REGISTERED_MESSAGE(BCGM_RESETTOOLBAR, OnToolbarReset)
ON_REGISTERED_MESSAGE(BCGM_TOOLBARMENU, OnToolbarContextMenu)

OnCreate()函式

CBCGPToolBar::EnableQuickCustomization ();

CBCGPToolBar::SetSizes (CSize (28, 28), CSize (22, 22));//工具欄大小
CBCGPToolBar::SetMenuSizes (CSize (22, 22), CSize (16, 16));//工具欄中下拉選單項大小

//指定常用的工具,其它會自動收縮。每個下拉(pulldown)選單條至少要有一項

CList<UINT, UINT> lstBasicCommands;

lstBasicCommands.AddTail (ID_VIEW_TOOLBARS);
lstBasicCommands.AddTail (ID_APP_EXIT);
lstBasicCommands.AddTail (ID_APP_ABOUT);
lstBasicCommands.AddTail (ID_VIEW_TOOLBAR);
lstBasicCommands.AddTail (ID_VIEW_CUSTOMIZE);
lstBasicCommands.AddTail (ID_COMMAND_HISTORY);
lstBasicCommands.AddTail (ID_VIEW_LARGEICON);
lstBasicCommands.AddTail (ID_VIEW_SMALLICON);
lstBasicCommands.AddTail (ID_VIEW_LIST);
lstBasicCommands.AddTail (ID_VIEW_DETAILS);
lstBasicCommands.AddTail (ID_EDIT_CUT);
lstBasicCommands.AddTail (ID_EDIT_COPY);
lstBasicCommands.AddTail (ID_EDIT_PASTE);

CBCGPToolBar::SetBasicCommands (lstBasicCommands);

if (!m_wndMenuBar.Create (this))//選單的建立
{
TRACE0("Failed to create menubar/n");
return -1; // fail to create
}

m_wndMenuBar.SetBarStyle(m_wndMenuBar.GetBarStyle() | CBRS_SIZE_DYNAMIC);

// Remove menubar gripper and borders:
m_wndMenuBar.SetBarStyle (m_wndMenuBar.GetBarStyle() &
~(CBRS_GRIPPER | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));

//動畫控制元件的建立,AFX_IDW_TOOLBAR為標準ID,IDB_ANIMATION是連續點陣圖

if (!m_wndAnimate.Create (_T(""), WS_CHILD | WS_VISIBLE, CRect(0, 0, 20, 20), this, AFX_IDW_TOOLBAR + 2) ||
!m_wndAnimate.SetBitmap (IDB_ANIMATION, 20))
{
TRACE0("Failed to create aimation/n");
return -1; // fail to create
}

m_wndAnimate.Play (500);

//檢測顏色深度是256還是真彩色

CClientDC dc (this);
BOOL bIsHighColor = dc.GetDeviceCaps (BITSPIXEL) > 8;

UINT uiToolbarHotID = bIsHighColor ? IDB_TOOLBAR256 : 0; //IDB_TOOLBAR256真彩色影象(用作工具欄)
UINT uiToolbarColdID = bIsHighColor ? IDB_TOOLBARCOLD256 : 0;
UINT uiMenuID = bIsHighColor ? IDB_MENU256 : IDB_MENU16;

if (!m_wndToolBar.CreateEx(this) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME, uiToolbarColdID, uiMenuID, FALSE, 0, 0, uiToolbarHotID))//IDR_MAINFRAME是256色的預定義工具欄
{
TRACE0("Failed to create toolbar/n");
return -1; // fail to create
}

// Remove toolbar gripper and borders:
m_wndToolBar.SetBarStyle (m_wndToolBar.GetBarStyle() &
~(CBRS_GRIPPER | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));

//建立位址列

if (!m_wndAddress.Create (CBS_DROPDOWN | WS_CHILD, CRect(0, 0, 200, 120), this, AFX_IDW_TOOLBAR + 1))
{
TRACE0("Failed to create combobox/n");
return -1; // fail to create
}

//將各項加入rebar面板
DWORD dwStyle = RBBS_GRIPPERALWAYS | RBBS_FIXEDBMP | RBBS_BREAK;

if (!m_wndReBar.Create(this) ||
!m_wndReBar.AddBar (&m_wndMenuBar) ||
!m_wndReBar.AddBar (&m_wndToolBar, NULL, NULL, dwStyle) ||
!m_wndReBar.AddBar(&m_wndAnimate, NULL, NULL, RBBS_FIXEDSIZE | RBBS_FIXEDBMP) ||
!m_wndReBar.AddBar(&m_wndAddress, _T("Address"), NULL, dwStyle))
{
TRACE0("Failed to create rebar/n");
return -1; // fail to create
}

m_wndMenuBar.AdjustLayout ();
m_wndToolBar.AdjustLayout ();

//--------------------------------------------------------------
// Set up min/max sizes and ideal sizes for pieces of the rebar:
//--------------------------------------------------------------
REBARBANDINFO rbbi;

CRect rectToolBar;
m_wndToolBar.GetItemRect(0, &rectToolBar);

rbbi.cbSize = sizeof(rbbi);
rbbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_SIZE;
rbbi.cxMinChild = rectToolBar.Width();
rbbi.cyMinChild = rectToolBar.Height();
rbbi.cx = rbbi.cxIdeal = rectToolBar.Width() * m_wndToolBar.GetCount ();
m_wndReBar.GetReBarCtrl().SetBandInfo (1, &rbbi);
rbbi.cxMinChild = 0;

CRect rectAddress;
m_wndAddress.GetEditCtrl()->GetWindowRect(&rectAddress);

rbbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE;
rbbi.cyMinChild = rectAddress.Height() + 10;
rbbi.cxIdeal = 200;
m_wndReBar.GetReBarCtrl().SetBandInfo (3, &rbbi);//基於上面的AddBar所定的順序

// 選單和工具欄允許增加自定義按鈕
m_wndMenuBar.EnableCustomizeButton (TRUE, (UINT)-1, _T(""));
m_wndToolBar.EnableCustomizeButton (TRUE, (UINT)-1, _T(""));

EnableDocking (CBRS_ALIGN_ANY);

m_wndReBar.EnableDocking (CBRS_TOP);//可以浮動和停靠
DockControlBar (&m_wndReBar);

CString strMainToolbarTitle;
strMainToolbarTitle.LoadString (IDS_MAIN_TOOLBAR);
m_wndToolBar.SetWindowText (strMainToolbarTitle);

// TODO: Remove this if you don't want tool tips
m_wndMenuBar.SetBarStyle(m_wndMenuBar.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY);
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY);

void CMainFrame::OnViewCustomize()
{
//------------------------------------
// Create a customize toolbars dialog:
//------------------------------------
CBCGPToolbarCustomize* pDlgCust = new CBCGPToolbarCustomize (this,
TRUE
);

pDlgCust->Create ();
}

LRESULT CMainFrame::OnToolbarContextMenu(WPARAM,LPARAM lp)
{
CPoint point (BCG_GET_X_LPARAM(lp), BCG_GET_Y_LPARAM(lp));

CMenu menu;
VERIFY(menu.LoadMenu (IDR_POPUP_TOOLBAR));

CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);

CBCGPPopupMenu* pPopupMenu = new CBCGPPopupMenu;
pPopupMenu->Create (this, point.x, point.y, pPopup->Detach ());

return 0;
}

//替換256色標準工具欄IDR_MAINFRAME為真彩色

afx_msg LRESULT CMainFrame::OnToolbarReset(WPARAM wp, LPARAM)
{
UINT uiToolBarId = (UINT) wp;
if (uiToolBarId != IDR_MAINFRAME)
{
return 0;
}

// Replace "Back" and "Forward" buttons by the menu buttons
// with the history lists:

CMenu menuHistory;
menuHistory.LoadMenu (IDR_HISTORY_POPUP);

CBCGPToolbarMenuButton btnBack (ID_GO_BACK, menuHistory,
CImageHash::GetImageOfCommand (ID_GO_BACK), _T("Back"));//帶選單的按鈕
btnBack.m_bText = TRUE;
m_wndToolBar.ReplaceButton (ID_GO_BACK, btnBack);

m_wndToolBar.ReplaceButton (ID_GO_FORWARD,
CBCGPToolbarMenuButton (ID_GO_FORWARD, menuHistory,
CImageHash::GetImageOfCommand (ID_GO_FORWARD), _T("Forward")));

// "Folders" button has a text label:
m_wndToolBar.SetToolBarBtnText (m_wndToolBar.CommandToIndex (ID_VIEW_FOLDERS),
_T("Folders"));

// Replace "Views" button by the menu button:
CMenu menuViews;
menuViews.LoadMenu (IDR_VIEWS_POPUP);

m_wndToolBar.ReplaceButton (ID_VIEW_VIEWS,
CBCGPToolbarMenuButton ((UINT)-1, menuViews,
CImageHash::GetImageOfCommand (ID_VIEW_VIEWS), _T("Views")));

return 0;
}

BOOL CMainFrame::OnShowPopupMenu (CBCGPPopupMenu* pMenuPopup)
{
//---------------------------------------------------------
// 將佔位的ID_VIEW_TOOLBARS選單項替換為IDR_POPUP_TOOLBAR:
//---------------------------------------------------------
CFrameWnd::OnShowPopupMenu (pMenuPopup);

if (pMenuPopup != NULL &&
pMenuPopup->GetMenuBar ()->CommandToIndex (ID_VIEW_TOOLBARS) >= 0)
{
if (CBCGPToolBar::IsCustomizeMode ())
{
//----------------------------------------------------
// Don't show toolbars list in the cuztomization mode!
//----------------------------------------------------
return FALSE;
}

pMenuPopup->RemoveAllItems ();

CMenu menu;
VERIFY(menu.LoadMenu (IDR_POPUP_TOOLBAR));

CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);

pMenuPopup->GetMenuBar ()->ImportFromMenu (*pPopup, TRUE);
}

return TRUE;
}

3.

補充CBCGPToolBar的使用

CMainFrame::OnCreate下

(1) CBCGPToolBar::EnableQuickCustomization ();//按Alt鍵時可以拖動工具欄上的圖示重新排列

(2) m_wndToolBar.EnableCustomizeButton (TRUE, ID_VIEW_CUSTOMIZE, _T("Customize..."));

//允許自定義工具欄,名字“Customize”,並與選單項ID_VIEW_CUSTOMIZE關聯。

【原創】BCGControlBar使用(三)
void CMainFrame::OnViewCustomize()
{//在BCG標準的自定義工具欄中加入新的屬性頁
CList <CRuntimeClass*, CRuntimeClass*> lstCustomPages;
lstCustomPages.AddTail (RUNTIME_CLASS (CMyCustomizationPage));

//CMyCustomizationPage是一個自定義的屬性頁
//------------------------------------
// Create a customize toolbars dialog:
//------------------------------------
CBCGPToolbarCustomize* pDlgCust = new CBCGPToolbarCustomize (this,
TRUE ,
BCGCUSTOMIZE_MENU_SHADOWS | BCGCUSTOMIZE_TEXT_LABELS |
BCGCUSTOMIZE_LOOK_2000 | BCGCUSTOMIZE_MENU_ANIMATIONS, // default parameters
&lstCustomPages); // pointer to the list of runtime classes of the custom property pages

pDlgCust->Create ();
}

(3)將佔位選單項ID_VIEW_TOOLBARS替換為選單IDR_POPUP_TOOLBAR

virtual BOOL OnShowPopupMenu (CBCGPPopupMenu* pMenuPopup);

BOOL CMainFrame::OnShowPopupMenu (CBCGPPopupMenu* pMenuPopup)
{
//---------------------------------------------------------
// Replace ID_VIEW_TOOLBARS menu item to the toolbars list:
//---------------------------------------------------------
CFrameWnd::OnShowPopupMenu (pMenuPopup);

if (pMenuPopup != NULL &&
pMenuPopup->GetMenuBar ()->CommandToIndex (ID_VIEW_TOOLBARS) >= 0)
{
if (CBCGPToolBar::IsCustomizeMode ())
{
//----------------------------------------------------
// Don't show toolbars list in the cuztomization mode!
//----------------------------------------------------
return FALSE;
}

pMenuPopup->RemoveAllItems ();

CMenu menu;
VERIFY(menu.LoadMenu (IDR_POPUP_TOOLBAR));

CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);

pMenuPopup->GetMenuBar ()->ImportFromMenu (*pPopup, TRUE);
}

return TRUE;
}