窗体类型的各种变换
窗体类型
一、 改变窗体外观
A、 在窗体创建前
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或
// 样式
//在此修改的项目是在窗体构建前所做的修改。
//cs.cx =300; //设置框架的宽度
//cs.cy =200; //设置框架的高度
//改变窗口的标题(而不是文档),窗口的标题cs.style是由FWS_ADDTOTITLE & WS_OVERLAPPEDWINDOW因此要改变窗口的标题
//就要去掉FWS_ADDTOTITLE。因此有如下3种方法去掉它。
/*cs.style &= ~FWS_ADDTOTITLE;
//cs.style=cs.style & ~FWS_ADDTOTITLE;
//cs.style=WS_OVERLAPPEDWINDOW; //WS_OVERLAPPEDWINDOW Creates an overlapped window with the WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, and WS_MAXIMIZEBOX styles.
cs.lpszName="http://volnet.cnblogs.com";
*/
return TRUE;
}
通过注册新类:(分别在MainFrm.cpp和StyleView.cpp中PreCreateWindow中改变)
//编写自己的窗口类,让随后的窗口创建由自己的代码来生成,但此时只修改了框架类的style,并没改变view类。
//方法一
/*WNDCLASS wndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wndcls.hCursor=LoadCursor(NULL,IDC_HELP);
wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);
wndcls.hInstance=AfxGetInstanceHandle();
wndcls.lpfnWndProc=::DefWindowProc;
wndcls.lpszClassName="volnet";
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndcls); //注册这个窗口类
cs.lpszClass="volnet"; //利用新建立的类(volnet),将cs.style的类型改变为“volnet”类型
*/
//方法二
//cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,0,0,LoadIcon(NULL,IDI_WARNING));
//如果都设置为缺省值
//cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);
B、在窗体创建后
在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)中添加:
//SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW); //去除文档标题
//利用GetWindowLong(m_hWnd,GWL_STYLE)来获得原先的窗体style,然后与现在要去掉的项目取反求补
SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE) & ~WS_MAXIMIZEBOX); //屏蔽最大化窗口
利用全局API函数SetClassLong()来修改类
//SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW); //去除文档标题
//利用GetWindowLong(m_hWnd,GWL_STYLE)来获得原先的窗体style,然后与现在要去掉的项目取反求补
//SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE) & ~WS_MAXIMIZEBOX); //屏蔽最大化窗口
设置可变化的图标
OnCreate
//不断变换的图标
/*m_hIcons[0]=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
m_hIcons[1]=LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ICON2));
m_hIcons[2]=LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDI_ICON3));
SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons[0]); //将第一幅图标设置为窗口的图标
SetTimer(1,1000,NULL);
*/
void CMainFrame::OnTimer(UINT nIDEvent)
{
static int index=1; //将其设置为1可以使初始显示的时候不会出现重复的图标(两个相同的连一起会造成不平滑)
SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons[index]);
index=++index%3;
二、 工具栏
1、 插入工具栏(添加资源)设计工具栏
2、 将工具栏添加进程序,设计停靠等功能
先转到定义,补充一个CToolBar m_newToolBar;
在OnCreate中添加
//创建工具栏,可以复制系统自带的工具栏并进行变量名修改(CBRS_TOP)被改为(CBRS_RIGHT),以修改放置位置
if (!m_newToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_RIGHT
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_newToolBar.LoadToolBar(IDR_TOOLBAR1))
{
TRACE0("未能创建工具栏\n");
return -1; // 未能创建
}
m_newToolBar.EnableDocking(CBRS_ALIGN_ANY);
//这句可不要,因为定义系统自带工具栏的时候,已经做过这项了EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_newToolBar);
添加菜单栏关于是否显示新的工具栏的选择条目。
1、 先在菜单中添加菜单项目
2、 添加事件处理程序
//显示/隐藏工具栏
//方法一
/*if(m_newToolBar.IsWindowVisible())
{
m_newToolBar.ShowWindow(SW_HIDE);
}
else
{
m_newToolBar.ShowWindow(SW_NORMAL);
}
RecalcLayout(); //用来调整因工具栏变动所导致的其他位置的变动
DockControlBar(&m_newToolBar); //将其停靠,然后才可处理已被拖动出来的工具栏的隐藏问题。
*/
//方法二(方法一如果将工具栏拖动出来,再还原的时候就无法在原位置显示,但在方法二中该问题得到解决,并且语句简洁)
ShowControlBar(&m_newToolBar,!m_newToolBar.IsWindowVisible(),FALSE);
3、 设置菜单上标题的复选标记
为菜单项“我的工具栏”添加事件处理,消息类型:UPDATE_COMMAND_UI
void CMainFrame::OnUpdateViewMytoolbar(CCmdUI *pCmdUI)
{
pCmdUI->SetCheck(m_newToolBar.IsWindowVisible());
}
三、 状态栏
1、 添加两个状态指示的栏
在MainFrm.cpp中找到以下黑色部分的定义,添加IDS_TIMER,IDS_PROGRESS
static UINT indicators[] =
{
ID_SEPARATOR, // 状态行指示器
IDS_TIMER, //新增的ID
IDS_PROGRESS, //新增的ID
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
在资源管理器中,找到StringTable,添加IDS_TIMER,IDS_PROGRESS以及中文。
2、 在“时钟”位置上显示当前时间
(在OnCreate和OnTimer中需同时存在以下代码,否则一开始将出现时钟两字)
CTime::GetCurrentTime();
SetPaneText(…);
SetPaneInfo(…);
CTime time=CTime::GetCurrentTime();
CString str=time.Format("%H:%M:%S");
//m_wndStatusBar.SetPaneText(1,str); //1是在定义的时候的索引号,假设不知道索引,可以用以下方法
int index=m_wndStatusBar.CommandToIndex(IDS_TIMER);
m_wndStatusBar.SetPaneText(index,str);
CClientDC dc(this);
CSize sz=dc.GetTextExtent(str);
m_wndStatusBar.SetPaneInfo(index,IDS_TIMER,SBPS_NORMAL,sz.cx); //让时间栏的显示大小能满足str的需要
3、 进度栏
(关于添加自定义消息,可以参考MSDNTN006: Message Maps)
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/vclib/html/_MFCNOTES_TN006.htm
在CMainFrm中定义一个进度栏
MainFrm.h中定义一个消息
#define UM_PROGRESS WM_USER+1 //自定义消息
afx_msg LRESULT OnProgress(WPARAM wParam, LPARAM lParam);
MainFrm.cpp中映射
ON_MESSAGE(UM_PROGRESS,OnProgress);
MainFrm.cpp中添加一个函数
LRESULT CMainFrame::OnProgress(WPARAM wParam, LPARAM lParam)
{
CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
m_progress.Create(WS_CHILD | WS_VISIBLE,rect,&m_wndStatusBar,123); //PBS_SMOOTH设置连续的进度栏
m_progress.SetPos(50); //设置进度的位置
return lParam;
}
MainFrm.cpp中OnCreate添加发送消息命令
PostMessage(UM_PROGRESS); //将消息加入消息队列然后返回,而SendMessage放进去后还要执行完才返回,如果调用OnPaint则可把此行注释掉
但如此的进度栏的位置会随着框架尺寸区域发生变化的时候就发生变化了。(位置不在我们要求的位置上)
窗口变化前:
窗口变化后:
因此在WM_PAINT中进行响应
void CMainFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
if(m_progress.m_hWnd==NULL) //因为进度栏已经创建了,如已经建了,则不用再建了,否则会出错
{
m_progress.Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH
,rect,&m_wndStatusBar,123); //PBS_SMOOTH设置连续的进度栏
}
else
m_progress.MoveWindow(&rect);
m_progress.SetPos(50); //设置进度的位置
// 不为绘图消息调用 CFrameWnd::OnPaint()
}
让进度条动起来
m_progress.StepIt();
4、 显示横纵坐标
void CStyleView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CString str;
str.Format("x=%d,y=%d",point.x,point.y);
//四种方法显示
//((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str); //方法一
//((CMainFrame*)GetParent())因为GetParent()返回的是CWnd的指针,而我们要的是(CMainFrame*)
//因此我们必须先进行强制转换,另外m_wndStatusBar是私有变量,我们无法调用,我们修改MainFrame.h
//中的相关定义来修改其类型(public:CStatusBar m_wndStatusBar;)
//((CMainFrame*)GetParent())->SetMessageText(str); //方法二
//((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(str); //方法三
GetParent()->GetDescendantWindow(AFX_IDW_STATUS_BAR)->SetWindowText(str); //方法四
CView::OnMouseMove(nFlags, point);
}
四、 启动画面(无法添加组件的方法)
1、 添加现有项目Splash.cpp和Splash.h,此两文件为VC6中添加组件所产生的CSplashWnd类的文件。附加完后类视图中出现新类
2、 添加资源,插入一个位图图片,ID为:IDB_SPLASH
3、 在CStyleApp类中重写BOOL CStyleApp::PreTranslateMessage(MSG* pMsg)加入如下代码
BOOL CStyleApp::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类
if (CSplashWnd::PreTranslateAppMessage(pMsg))
return TRUE;
return CWinApp::PreTranslateMessage(pMsg);
}
4、 在InitInstance();中添加:
BOOL CStyleApp::InitInstance()
{
// 以下模块创建了一个启动画面
{
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
CSplashWnd::EnableSplashScreen(cmdInfo.m_bShowSplash);
}
…………………………………………………………………..
5、 包含头文件#include “Splash.h”
6、 在MainFrame.cpp中的OnCreate()中添加:
CSplashWnd::ShowSplashScreen(this);
7、 改变启动画面停留时间
在CSplashWnd类中的OnCreate()函数中修改SetTimer(1, 3000, NULL);
其中3000就表示停留时间,为3000毫秒
posted on 2008-07-18 20:10 volnet(可以叫我大V) 阅读(1478) 评论(0) 编辑 收藏 举报