home *** CD-ROM | disk | FTP | other *** search
- // Dlgcbr32.cpp : Defines the class behaviors for CModelessMain.
- //
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
- #include "stdafx.h"
- #include <afxpriv.h>
- #include "mdlsmain.h"
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain
-
- IMPLEMENT_DYNAMIC(CModelessMain, CModelessDialog)
-
- BEGIN_MESSAGE_MAP(CModelessMain, CModelessDialog)
- //{{AFX_MSG_MAP(CModelessMain)
- ON_WM_CLOSE()
- ON_WM_PAINT()
- ON_WM_ERASEBKGND()
- ON_WM_QUERYDRAGICON()
- ON_WM_ENTERIDLE()
- ON_WM_INITMENUPOPUP()
- ON_WM_MENUSELECT()
- ON_MESSAGE(WM_SETMESSAGESTRING, OnSetMessageString)
- ON_MESSAGE(WM_POPMESSAGESTRING, OnPopMessageString)
- //}}AFX_MSG_MAP
- ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
- ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
-
- // Standard View menu options
- ON_COMMAND(ID_VIEW_STATUS_BAR, OnStatusBarCheck)
- ON_COMMAND(ID_VIEW_TOOLBAR, OnToolBarCheck)
- ON_UPDATE_COMMAND_UI(ID_VIEW_STATUS_BAR, OnUpdateStatusBarMenu)
- ON_UPDATE_COMMAND_UI(ID_VIEW_TOOLBAR, OnUpdateToolBarMenu)
-
- // Standard status bar mode indicators
- ON_UPDATE_COMMAND_UI(ID_INDICATOR_CAPS, OnUpdateKeyIndicator)
- ON_UPDATE_COMMAND_UI(ID_INDICATOR_NUM, OnUpdateKeyIndicator)
- ON_UPDATE_COMMAND_UI(ID_INDICATOR_SCRL, OnUpdateKeyIndicator)
-
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain Construction/Destruction
-
- CModelessMain::CModelessMain()
- {
- m_hIcon = NULL;
-
- m_nIDTracking = 0;
- m_nIDLastMessage = 0;
-
- m_lpaIDStatusBar = NULL;
- m_cIDStatusBar = 0;
-
- m_lpaIDToolBar = NULL;
- m_cIDToolBar = 0;
- m_nIDBitmap = 0;
- }
-
- CModelessMain::~CModelessMain()
- {
- }
-
- ////////////////////////////////////////////////////////////////////////////
- // CModelessMain::Create
- // Create saves away information about the status bar and toolbar,
- // loads the dialog icon, and creates the dialog window. It assumes
- // the dialog icon has the same resource ID as the dialog template
- // itself.
-
- BOOL CModelessMain::Create(UINT nIDTemplate,
- const UINT FAR* lpaIDStatus, int cIDStatus,
- const UINT FAR* lpaIDToolbar, int cIDToolbar,
- UINT nIDBitmap)
- {
- m_hIcon = AfxGetApp()->LoadIcon(nIDTemplate);
-
- m_lpaIDStatusBar = lpaIDStatus;
- m_cIDStatusBar = cIDStatus;
-
- m_lpaIDToolBar = lpaIDToolbar;
- m_cIDToolBar = cIDToolbar;
- m_nIDBitmap = nIDBitmap;
-
- return CModelessDialog::Create(nIDTemplate);
- }
-
- BOOL CModelessMain::Create(LPCSTR lpszTemplateName,
- const UINT FAR* lpaIDStatus, int cIDStatus,
- const UINT FAR* lpaIDToolbar, int cIDToolbar,
- UINT nIDBitmap)
- {
- ASSERT(lpszTemplateName != NULL);
-
- m_hIcon = AfxGetApp()->LoadIcon(lpszTemplateName);
-
- m_lpaIDStatusBar = lpaIDStatus;
- m_cIDStatusBar = cIDStatus;
-
- m_lpaIDToolBar = lpaIDToolbar;
- m_cIDToolBar = cIDToolbar;
- m_nIDBitmap = nIDBitmap;
-
- return CModelessDialog::Create(lpszTemplateName);
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnClose
- // OnClose handles the WM_CLOSE message by posting a WM_QUIT message
- // (so the app shuts down), after performing default processing to
- // actually close the window.
-
- void CModelessMain::OnClose()
- {
- CModelessDialog::OnClose();
- PostQuitMessage(0);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnInitDialog
- // OnInitDialog centers the dialog on the screen and creates the status
- // and toolbars. To make sure the control bars don't overlap any
- // dialog controls, the dialog's client area is expanded by the amount
- // of space required for the control bars.
-
- BOOL CModelessMain::OnInitDialog()
- {
- CModelessDialog::OnInitDialog();
-
- // Create status bar at the bottom of the dialog window
- if (m_statusBar.Create(this))
- {
- m_statusBar.SetIndicators(m_lpaIDStatusBar, m_cIDStatusBar);
- OnSetMessageString(AFX_IDS_IDLEMESSAGE);
-
- // Make a sunken or recessed border around the first pane
- m_statusBar.SetPaneInfo(0, m_statusBar.GetItemID(0),
- SBPS_STRETCH, NULL );
- }
-
- // Create toolbar at the top of the dialog window
- if (m_toolBar.Create(this))
- {
- m_toolBar.LoadBitmap(m_nIDBitmap);
- m_toolBar.SetButtons(m_lpaIDToolBar, m_cIDToolBar);
- }
-
- m_toolBar.SetBarStyle(m_toolBar.GetBarStyle() |
- CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
-
- // We need to resize the dialog to make room for control bars.
- // First, figure out how big the control bars are.
- CRect rcClientStart;
- CRect rcClientNow;
- GetClientRect(rcClientStart);
- RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST,
- 0, reposQuery, rcClientNow);
-
- // Now move all the controls so they are in the same relative
- // position within the remaining client area as they would be
- // with no control bars.
- CPoint ptOffset(rcClientNow.left - rcClientStart.left,
- rcClientNow.top - rcClientStart.top);
-
- CRect rcChild;
- CWnd* pwndChild = GetWindow(GW_CHILD);
- while (pwndChild)
- {
- pwndChild->GetWindowRect(rcChild);
- ScreenToClient(rcChild);
- rcChild.OffsetRect(ptOffset);
- pwndChild->MoveWindow(rcChild, FALSE);
- pwndChild = pwndChild->GetNextWindow();
- }
-
- // Adjust the dialog window dimensions
- CRect rcWindow;
- GetWindowRect(rcWindow);
- rcWindow.right += rcClientStart.Width() - rcClientNow.Width();
- rcWindow.bottom += rcClientStart.Height() - rcClientNow.Height();
- MoveWindow(rcWindow, FALSE);
-
- // And position the control bars
- RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
-
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
-
- // Finally, center the dialog on the screen
- CenterWindow();
- return TRUE;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnPaint
- // CModelessMain::OnEraseBkgnd
- // CModelessMain::OnQueryDragIcon
- // These functions are used to display a custom icon for the dialog.
- //
- // These functions use a technique described in KB article Q87976
- // to display a custom icon for our dialog window. We assume that
- // the icon has been loaded into m_hIcon.
-
- void CModelessMain::OnPaint()
- {
- CPaintDC dc(this);
- if (IsIconic() && m_hIcon)
- {
- // Erase the icon background when placed over other app window
- DefWindowProc(WM_ICONERASEBKGND, (WORD)dc.m_hDC, 0L);
-
- // Center the icon
- CRect rc;
- GetClientRect(&rc);
- rc.left = (rc.right - ::GetSystemMetrics(SM_CXICON))/2;
- rc.top = (rc.bottom - ::GetSystemMetrics(SM_CYICON))/2;
-
- // Draw the icon
- dc.DrawIcon(rc.left, rc.top, m_hIcon);
- }
- }
-
- BOOL CModelessMain::OnEraseBkgnd(CDC* pDC)
- {
- if (IsIconic() && m_hIcon)
- return TRUE;
- else
- return CModelessDialog::OnEraseBkgnd(pDC);
- }
-
- HCURSOR CModelessMain::OnQueryDragIcon()
- {
- return (HCURSOR)m_hIcon;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnInitMenuPopup
- // OnInitMenuPopup updates the state of items on a popup menu.
- //
- // This code is based on CFrameWnd::OnInitMenuPopup. We assume the
- // application does not support context sensitive help.
-
- void CModelessMain::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
- {
- if (!bSysMenu)
- {
- ASSERT(pPopupMenu != NULL);
-
- // check the enabled state of various menu items
- CCmdUI state;
- state.m_pMenu = pPopupMenu;
- ASSERT(state.m_pOther == NULL);
-
- state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
- for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
- state.m_nIndex++)
- {
- state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
- if (state.m_nID == 0)
- continue; // menu separator or invalid cmd - ignore it
-
- ASSERT(state.m_pOther == NULL);
- ASSERT(state.m_pMenu != NULL);
- if (state.m_nID == (UINT)-1)
- {
- // possibly a popup menu, route to first item of that popup
- state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex);
- if (state.m_pSubMenu == NULL ||
- (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
- state.m_nID == (UINT)-1)
- {
- continue; // first item of popup can't be routed to
- }
- state.DoUpdate(this, FALSE); // popups are never auto disabled
- }
- else
- {
- // normal menu item
- // Auto enable/disable if command is _not_ a system command
- state.m_pSubMenu = NULL;
- state.DoUpdate(this, state.m_nID < 0xF000);
- }
- }
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnEnterIdle
- // OnEnterIdle updates the status bar when there's nothing better to do.
- // This code is based on CFrameWnd::OnEnterIdle.
-
- void CModelessMain::OnEnterIdle(UINT nWhy, CWnd* pWho)
- {
- if (nWhy != MSGF_MENU || m_nIDTracking == m_nIDLastMessage)
- return;
-
- OnSetMessageString(m_nIDTracking);
- ASSERT(m_nIDTracking == m_nIDLastMessage);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnMenuSelect
- // OnMenuSelect updates the status bar message, based on the state
- // of the dialog menu.
- //
- // This code is based on CFrameWnd::OnMenuSelect. We assume the
- // application does not support context sensitive help.
-
- void CModelessMain::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
- {
- // set the tracking state
- if (nFlags == 0xFFFF)
- {
- // cancel menu operation (go back to idle now)
- m_nIDTracking = AFX_IDS_IDLEMESSAGE;
- OnSetMessageString(m_nIDTracking); // set string now
- ASSERT(m_nIDTracking == m_nIDLastMessage);
- }
- else if (nItemID == 0 ||
- nFlags & (MF_SEPARATOR|MF_POPUP|MF_MENUBREAK|MF_MENUBARBREAK))
- {
- // nothing should be displayed
- m_nIDTracking = 0;
- }
- else if (nItemID >= 0xF000 && nItemID < 0xF1F0)
- {
- // special string table entries for system commands
- m_nIDTracking = ID_COMMAND_FROM_SC(nItemID);
- ASSERT(m_nIDTracking >= AFX_IDS_SCFIRST &&
- m_nIDTracking < AFX_IDS_SCFIRST + 31);
- }
- else
- {
- // track on idle
- m_nIDTracking = nItemID;
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnSetMessageString
- // OnSetMessageString updates the status bar text.
- //
- // This code is based on CFrameWnd::OnSetMessageString. We assume
- // a string ID is always passed in wParam.
-
- LRESULT CModelessMain::OnSetMessageString(WPARAM wParam, LPARAM lParam)
- {
- UINT nIDMsg = (UINT)wParam;
- CString strMsg;
-
- if (nIDMsg)
- {
- if (strMsg.LoadString(nIDMsg) != 0)
- m_statusBar.SetWindowText(strMsg);
- else
- TRACE1("Warning: no message line prompt for ID %x%04X\n", nIDMsg);
- }
-
- UINT nIDLast = m_nIDLastMessage;
- m_nIDLastMessage = nIDMsg;
- m_nIDTracking = nIDMsg;
- return nIDLast;
-
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnStatusBarCheck
- // OnStatusBarCheck toggles the status of the status bar when the
- // corresponding View option is selected from the menu.
-
- void CModelessMain::OnStatusBarCheck()
- {
- m_statusBar.ShowWindow(m_statusBar.IsWindowVisible() ? SW_HIDE : SW_SHOWNA);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnUpdateStatusBarMenu
- // OnUpdateStatusBarMenu checks or unchecks the View option,
- // depending on whether or not the status bar is visible.
-
- void CModelessMain::OnUpdateStatusBarMenu(CCmdUI* pCmdUI)
- {
- ASSERT(pCmdUI->m_nID == ID_VIEW_STATUS_BAR);
- pCmdUI->SetCheck(m_statusBar.IsWindowVisible());
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnToolBarCheck
- // OnToolBarCheck toggles the status of the toolbar when the
- // corresponding View option is selected from the menu.
-
- void CModelessMain::OnToolBarCheck()
- {
- m_toolBar.ShowWindow(m_toolBar.IsWindowVisible() ? SW_HIDE : SW_SHOWNA);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnUpdateToolBarMenu
- // OnUpdateToolBarMenu checks or unchecks the View option,
- // depending on whether or not the toolbar is visible.
-
- void CModelessMain::OnUpdateToolBarMenu(CCmdUI* pCmdUI)
- {
- ASSERT(pCmdUI->m_nID == ID_VIEW_TOOLBAR);
- pCmdUI->SetCheck(m_toolBar.IsWindowVisible());
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnUpdateKeyIndicator
- // OnUpdateKeyIndicator enables or disables one of the key indicators
- // in a status bar. It recognizes the CAPS, NUM, and SCRL keys.
-
- void CModelessMain::OnUpdateKeyIndicator(CCmdUI* pCmdUI)
- {
- UINT nVK;
-
- switch (pCmdUI->m_nID)
- {
- case ID_INDICATOR_CAPS:
- nVK = VK_CAPITAL;
- break;
-
- case ID_INDICATOR_NUM:
- nVK = VK_NUMLOCK;
- break;
-
- case ID_INDICATOR_SCRL:
- nVK = VK_SCROLL;
- break;
-
- default:
- TRACE1("Warning: OnUpdateKeyIndicator - unknown indicator 0x%04X\n",
- pCmdUI->m_nID);
- pCmdUI->ContinueRouting();
- return; // not for us
- }
-
- pCmdUI->Enable(::GetKeyState(nVK) & 1);
- // enable static text based on toggled key state
- ASSERT(pCmdUI->m_bEnableChanged);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnPopMessageString
- // Resets status bar message string. This code is based on
- // CFrameWnd::OnPopMessageString
-
- LRESULT CModelessMain::OnPopMessageString(WPARAM wParam, LPARAM lParam)
- {
- if (m_nFlags & WF_NOPOPMSG)
- return 0;
-
- return SendMessage(WM_SETMESSAGESTRING, wParam, lParam);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CModelessMain::OnToolTipText
- // Handles TTN_NEEDTEXT message to display tooltips for the toolbar.
- // This code is based on CFrameWnd::OnToolTipText
-
- BOOL CModelessMain::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)
- {
- ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
-
- // allow top level routing frame to handle the message
- if (GetRoutingFrame() != NULL)
- return FALSE;
-
- // need to handle both ANSI and UNICODE versions of the message
- TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
- TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
- TCHAR szFullText[256];
- CString strTipText;
- UINT nID = pNMHDR->idFrom;
- if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
- pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
- {
- // idFrom is actually the HWND of the tool
- nID = ((UINT)(WORD)::GetDlgCtrlID((HWND)nID));
- }
-
- if (nID != 0) // will be zero on a separator
- {
- AfxLoadString(nID, szFullText);
- // this is the command id, not the button index
- AfxExtractSubString(strTipText, szFullText, 1, '\n');
- }
- #ifndef _UNICODE
- if (pNMHDR->code == TTN_NEEDTEXTA)
- lstrcpyn(pTTTA->szText, strTipText,
- (sizeof(pTTTA->szText)/sizeof(pTTTA->szText[0])));
- else
- _mbstowcsz(pTTTW->szText, strTipText,
- (sizeof(pTTTW->szText)/sizeof(pTTTW->szText[0])));
- #else
- if (pNMHDR->code == TTN_NEEDTEXTA)
- _wcstombsz(pTTTA->szText, strTipText,
- (sizeof(pTTTA->szText)/sizeof(pTTTA->szText[0])));
- else
- lstrcpyn(pTTTW->szText, strTipText,
- (sizeof(pTTTW->szText)/sizeof(pTTTW->szText[0])));
- #endif
- *pResult = 0;
-
- // bring the tooltip window above other popup windows
- ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
- SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE);
-
- return TRUE; // message was handled
- }
-