Figure 1 Mouse
Hit-test Codes
Code
|
Mouse
Location
|
HTBORDER
|
In the border of a
window that does not have a sizing border. Use to disallow moving or
sizing. Can still be used to activate app.
|
HTBOTTOM
|
In the lower
horizontal border of the window
|
HTBOTTOMLEFT
|
In the lower-left
corner of the window border
|
HTBOTTOMRIGHT
|
In the lower-right
corner of the window border
|
HTCAPTION
|
In a title-bar
area
|
HTCLIENT
|
In a client
area
|
HTERROR
|
On the screen
background or on a dividing line between windows (same as HTNOWHERE except
that the DefWndProc Windows function produces a system beep to indicate an
error)
|
HTGROWBOX
|
In a size
box
|
HTHSCROLL
|
In the horizontal
scroll bar
|
HTLEFT
|
In the left border of
the window
|
HTMAXBUTTON
|
In a Maximize
button
|
HTMENU
|
In a menu
area
|
HTMINBUTTON
|
In a Minimize
button
|
HTNOWHERE
|
On the screen
background or on a dividing line between windows
|
HTREDUCE
|
In a Minimize
button
|
HTRIGHT
|
In the right border of
the window
|
HTSIZE
|
In a size box (same as
HTGROWBOX)
|
HTSYSMENU
|
In a Control menu or
in a Close button in a child window
|
HTTOP
|
In the upper
horizontal border of the window
|
HTTOPLEFT
|
In the upper-left
corner of the window border
|
HTTOPRIGHT
|
In the upper-right
corner of the window border
|
HTTRANSPARENT
|
In a window currently
covered by another window
|
HTVSCROLL
|
In the vertical scroll
bar
|
HTZOOM
|
In a Maximize
button
|
Figure 2 MainFrm
MainFrm.h ////////////////////////////////////////////////////////////////
// VCKBASE -- February 2001
// Visual C++ 6.0编译, Windows 98/NT 运行通过.
//
#pragma once
class CMyView;
class CMySplitterWnd : public CSplitterWnd {
public:
CMySplitterWnd();
~CMySplitterWnd();
protected:
afx_msg void OnLButtonDown(UINT, CPoint);
afx_msg void OnMouseMove(UINT, CPoint);
DECLARE_MESSAGE_MAP()
};
class CMainFrame : public CFrameWnd {
public:
virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs,
CCreateContext* pContext);
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual ~CMainFrame();
CMyView* GetRightPane();
protected: // create from serialization only
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
CMySplitterWnd m_wndSplitter;
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
CReBar m_wndReBar;
afx_msg UINT OnNcHitTest(CPoint point);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnUpdateViewStyles(CCmdUI* pCmdUI);
afx_msg void OnViewStyle(UINT nCommandID);
DECLARE_MESSAGE_MAP()
};
MainFrm.cpp ////////////////////////////////////////////////////////////////
// VCKBASE -- February 2001
// Visual C++ 6.0编译, Windows 98/NT 运行通过.
//
#include "stdafx.h"
#include "NoSize.h"
#include "MainFrm.h"
#include "LeftView.h"
#include "View.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_NCHITTEST()
ON_WM_CREATE()
ON_UPDATE_COMMAND_UI_RANGE(AFX_ID_VIEW_MINIMUM, AFX_ID_VIEW_MAXIMUM,
OnUpdateViewStyles)
ON_COMMAND_RANGE(AFX_ID_VIEW_MINIMUM, AFX_ID_VIEW_MAXIMUM, OnViewStyle)
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
}
CMainFrame::~CMainFrame()
{
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style &= ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
return CFrameWnd::PreCreateWindow(cs);
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) {
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndReBar.Create(this) ||
!m_wndReBar.AddBar(&m_wndToolBar)) {
TRACE0("Failed to create rebar\n");
return -1; // fail to create
}
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY);
// 从系统菜单中取缔 移动/大小/最大化/最小化选项
static UINT BadCommands[] = {
SC_SIZE, SC_MOVE, SC_MINIMIZE, SC_MAXIMIZE, SC_RESTORE, 0 };
CMenu *pSysMenu = GetSystemMenu(FALSE);
for (int i=0; BadCommands[i]; i++) {
pSysMenu->RemoveMenu(BadCommands[i], MF_BYCOMMAND);
}
// 蒙骗MFC创建没有尺寸手柄的状态条
// MFC 使用 WS_THICKFRAME 确定状态条是否有尺寸手柄
// 所以临时屏蔽掉 WS_THICKFRAME
//
ModifyStyle(WS_THICKFRAME,0);
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT))) {
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
ModifyStyle(0,WS_THICKFRAME); // 恢复 WS_THICKFRAME
return 0;
}
#ifdef _DEBUG
struct {
UINT id;
LPCTSTR name;
} HtCodes[] = {
{ HTNOWHERE,"HTNOWHERE" },
{ HTCLIENT,"HTCLIENT" },
{ HTCAPTION,"HTCAPTION" },
{ HTSYSMENU,"HTSYSMENU" },
{ HTSIZE,"HTSIZE" },
{ HTMENU,"HTMENU" },
{ HTHSCROLL,"HTHSCROLL" },
{ HTVSCROLL,"HTVSCROLL" },
{ HTMINBUTTON,"HTMINBUTTON" },
{ HTMAXBUTTON,"HTMAXBUTTON" },
{ HTLEFT,"HTLEFT" },
{ HTRIGHT,"HTRIGHT" },
{ HTTOP,"HTTOP" },
{ HTTOPLEFT,"HTTOPLEFT" },
{ HTTOPRIGHT,"HTTOPRIGHT" },
{ HTBOTTOM,"HTBOTTOM" },
{ HTBOTTOMLEFT,"HTBOTTOMLEFT" },
{ HTBOTTOMRIGHT,"HTBOTTOMRIGHT" },
{ HTBORDER,"HTBORDER" },
{ HTOBJECT,"HTOBJECT" },
{ HTCLOSE,"HTCLOSE" },
{ HTHELP,"HTHELP" },
{ 0,NULL },
};
#endif
//////////////////
// 重载后不接受 移动/大小 调整操作
//
UINT CMainFrame::OnNcHitTest(CPoint point)
{
UINT hit = CFrameWnd::OnNcHitTest(point);
#ifdef _DEBUG
// 用于调试, 现实缺省的鼠标点击代码
LPCTSTR s = "Unknown";
for (int i=0; HtCodes[i].name; i++) {
if (hit == HtCodes[i].id) {
s = HtCodes[i].name;
break;
}
}
#endif
// 不接受一下代码值: 映射到 HTNOWHERE
static char DisallowCodes[] = {
HTLEFT,HTRIGHT,HTTOP,HTTOPLEFT,HTTOPRIGHT,
HTBOTTOM,HTBOTTOMLEFT,HTBOTTOMRIGHT,HTSIZE,HTCAPTION };
TRACE(_T("CMainFrame::OnNcHitTest: %s"), s);
if (strchr(DisallowCodes, hit)) {
TRACE(" — disallowed\n");
return HTBORDER;
}
TRACE("\n");
return hit;
}
////////////////////////////////////////////////////////////////
// Rest is generic MFC stuff
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,
CCreateContext* pContext)
{
// 创建切分窗口
if (!m_wndSplitter.CreateStatic(this, 1, 2))
return FALSE;
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView), CSize(100,
100), pContext) ||
!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CMyView), CSize(100,
100), pContext))
{
m_wndSplitter.DestroyWindow();
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
CMyView* CMainFrame::GetRightPane()
{
CWnd* pWnd = m_wndSplitter.GetPane(0, 1);
CMyView* pView = DYNAMIC_DOWNCAST(CMyView, pWnd);
return pView;
}
void CMainFrame::OnUpdateViewStyles(CCmdUI* pCmdUI)
{
CMyView* pView = GetRightPane();
if (pView == NULL)
pCmdUI->Enable(FALSE);
else {
DWORD dwStyle = pView->GetStyle() & LVS_TYPEMASK;
if (pCmdUI->m_nID == ID_VIEW_LINEUP) {
if (dwStyle == LVS_ICON || dwStyle == LVS_SMALLICON)
pCmdUI->Enable();
else
pCmdUI->Enable(FALSE);
} else {
pCmdUI->Enable();
BOOL bChecked = FALSE;
switch (pCmdUI->m_nID) {
case ID_VIEW_DETAILS:
bChecked = (dwStyle == LVS_REPORT);
break;
case ID_VIEW_SMALLICON:
bChecked = (dwStyle == LVS_SMALLICON);
break;
case ID_VIEW_LARGEICON:
bChecked = (dwStyle == LVS_ICON);
break;
case ID_VIEW_LIST:
bChecked = (dwStyle == LVS_LIST);
break;
default:
bChecked = FALSE;
break;
}
pCmdUI->SetRadio(bChecked ? 1 : 0);
}
}
}
void CMainFrame::OnViewStyle(UINT nCommandID)
{
CMyView* pView = GetRightPane();
if (pView != NULL) {
DWORD dwStyle = -1;
switch (nCommandID) {
case ID_VIEW_LINEUP: {
CListCtrl& refListCtrl = pView->GetListCtrl();
refListCtrl.Arrange(LVA_SNAPTOGRID);
}
break;
case ID_VIEW_DETAILS:
dwStyle = LVS_REPORT;
break;
case ID_VIEW_SMALLICON:
dwStyle = LVS_SMALLICON;
break;
case ID_VIEW_LARGEICON:
dwStyle = LVS_ICON;
break;
case ID_VIEW_LIST:
dwStyle = LVS_LIST;
break;
}
if (dwStyle != -1)
pView->ModifyStyle(LVS_TYPEMASK, dwStyle);
}
}
////////////////////////////////////////////////////////////////
// CMySplitterWnd — disallow moving the splitter interactively
//
BEGIN_MESSAGE_MAP(CMySplitterWnd, CSplitterWnd)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
CMySplitterWnd::CMySplitterWnd()
{
}
CMySplitterWnd::~CMySplitterWnd()
{
}
// override: don't allow resize
void CMySplitterWnd::OnLButtonDown(UINT, CPoint)
{
return; // 就这么简单
}
// override: don't allow setting cursor
void CMySplitterWnd::OnMouseMove(UINT, CPoint)
{
return;//同上
}