MFC学习笔记(7)

这几天 又跑去研究CE了—— 忽略MFC了   过几天做下CE的笔记   不是WinCE  是Cheat.Engine

使窗口重绘三种方法:    
  1.直接调用窗口的OnPaint()  
  2.调用RedrawWindow()  
  3.发送WM_PAINT消息

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
最正确的解决方案
ls 的各位可能你们用的不是 VS2008.
由于 VS2008 sp1 引用了 BCG 的包,而 BCG 为了方便程序员,
在注册表中保存了窗口的大小、位置等信息,包括工具栏的相应信息。
这样减少了程序员保存和恢复用户上次使用过的界面的重复劳动。

而对于刚开始接触 BCG 的人,可能不知道这些,比如 lz (我不是笑话你的意思,别误会)
所以尝试改变对话框大小的时候就会发现改变不了,原因就是你的程序之前至少运行过一次,
以后运行的话就会载入他上一次关闭时的大小和位置。所以给你的错觉就是你以为你的代码没有起作用。

而事实是,你的代码是完全对的,你要做的就是删除 BCG 为你保存的注册表键:
HKEY_CURRENT_USER/Software/[your corporation]/[your application]/Workspace
里面 your corporation 是指在 app 类里面 SetRegistryKey 指定的路径;your application 就是你的应用程序名。

把这个删掉之后,还是用你最上面的代码,运行。OK! 

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
改变窗口样式
CMainFrame::PreCreateWindow中改是在创建窗口前改
SetWindowLong是在创建窗口后改
例:SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW);
GetWindowLong可以在现有样式上进行修改
例:SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE)&~WS_MAXIMIZEBOX);


改变窗口图标 光标 背景可以编写自己的窗口类  让之后的窗口按照自己的窗口类来创建
可以在view类的PreCreateWindow中编写窗口类

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();//返回应用程序句柄Afx开头函数是MFC全局函数
wndcls.lpfnWndProc=::DefWindowProc;//窗口过程
wndcls.lpszClassName=L"fengjiang";
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW|CS_VREDRAW;

RegisterClass(&wndcls);//注册窗口类

cs.lpszClass="fengjiang";//把窗口类改成自己定义的

注意view是覆盖在框架窗口上的  如果要修改图标 需要在框架窗口上编写窗口类  如果是在view类上的光标和背景需要在view类中编写  
自定义窗口类的方法很是麻烦下面我们用一个全局函数 搞定之
在框架类的PreCreateWindow中可以用它改图标
在view类中可以用它改背景和光标
AfxRegisterWndClass
框架类中:
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,0,0,LoadIcon(NULL,IDI_WARNING));

view类中:
cs.lpszClaee=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,LoadCursor(NULL,IDC_CROSS),(HBRUSH)GetStockObject(BLACK_BRUSH),0);

上述方法是在创建窗口前改变图标光标等

有一个全局函数可以在创建窗口后修改
SetClassLong
例:SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)LoadCursor(NULL,IDC_HELP));

图标动画效果 
用SetClassLong每隔一段时间换一下图标   用SetTimer实现
添加WM_TIMER消息响应函数 
*把一个值始终控制在一个范围内  最好的方法是取模
例如:index=++index%3;

创建自己的工具栏
(1)
1.Create a toolbar resource.

2.Construct the CToolBar object.

3.Call the Create (or CreateEx) function to create the Windows toolbar and attach it to the CToolBar object.

4.Call LoadToolBar to load the toolbar resource.

按照上述方法操作下来 发生了错误   我是废了不少心思   才知道 是因为VS2008中  创建这个工具栏  用的是CMFCToolBar   CToolBar适用于VC6++ 

我把VS2008下实现的代码写下来
CMFCToolBar m_mybar;

。。。。。。。

 if (!m_mybar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
  !m_mybar.LoadToolBar(IDR_TOOLBAR1))
 {
  TRACE0("未能创建工具栏/n");
  return -1;      // 未能创建
 }
 m_mybar.EnableDocking(CBRS_ALIGN_ANY);//可停靠
 DockPane(&m_mybar);  //停靠在主框架窗口上


另外

如果定义的是CToolBar类,如:CToolBar m_wndToolBar;

当需要显示或隐藏工具栏是可以使用showcontrolbar(&m_wndToolBar,TRUE/FALSE, FALSE)来实现。然后一开始定义的是CMFCToolBar类时,如:CMFCToolBar m_wndToolBar;不能用showcontrolbar实现隐藏和显示,因为showcontrolbar()的第一个参数是CToolBar类型。这时可以调用ShowWindow(SW_SHOW/SW_HIDE)实现:m_wndToolBar.ShowWindow(SW_SHOW/SW_HIDE)。

 if(m_mybar.IsWindowVisible())
 {
  m_mybar.ShowWindow(SW_HIDE);
 }
 else
 {
  m_mybar.ShowWindow(SW_SHOW);
 }
 RecalcLayout();  //恢复原样
 DockPane(&m_mybar); //停靠工具栏
在上述基础上如果要给菜单项做复选  首先 给菜单项增加一个UPDATE_COMMAND_UI的命令相应   然后进去pCmdUI->SetCheck(m_mybar.IsWindowVisible());

*由于无法适应VS2008 带来的改变  我在学MFC当中遇到了不少麻烦  这个笔记做完之后  准备专门把我在编程中遇到的VS2008与VC6++的几个不同之处总结一下   也算是造福人类了 汗——

工具栏的ID和菜单项里对应功能的项的ID是一样的  直接在菜单里相应功能就可以了

创建状态栏窗格
首先创建string table项
然后在static UINT indicators[]中添加string table项ID


 CTime t = CTime::GetCurrentTime();  
 CString str=t.Format(L"%H:%M:%S");
 CClientDC dc(this);
 CSize sz=dc.GetTextExtent(str);
 m_wndStatusBar.SetPaneInfo(1,IDS_TIMER,SBPS_NORMAL,sz.cx); //设置窗格宽度
 m_wndStatusBar.SetPaneText(1,str);
 CFrameWndEx::OnTimer(nIDEvent);


 CRect rect;
 m_wndStatusBar.GetItemRect(2,&rect);
 if(!m_myCtrl.m_hWnd)
 {
  m_myCtrl.Create(WS_CHILD|WS_VISIBLE|PBS_SMOOTH,rect, &m_wndStatusBar, 123);
 }
 else
 {
  m_myCtrl.MoveWindow(rect);
 }
 m_myCtrl.SetPos(50);

让进度前进  有SetpIt和SetRange


任何自定义消息
首先在头文件中定义
#define  UM_MY     WM_USER+1 //系统消息ID都在WM_USER之下
然后在头文件中声明消息响应函数
afx_msg void OnMy();
之后建立消息映射  将消息与消息响应函数关联起来
ON_MESSAGE(UM_MY,OnMy)
最后写消息响应函数的实现部分

SendMessage是直接把消息发给消息响应函数  执行后然后再返回
PostMessage是把消息放到消息队列中  就立即返回

在状态栏上 显示鼠标坐标
///
void CStyleView::OnMouseMove(UINT nFlags, CPoint point)
{
 CString str;
 str.Format(L"x=%d,y=%d",point.x,point.y);
 ((CMainFrame *)GetParent())->m_wndStatusBar.SetWindowText(str);
//((CMainFrame *)GetParent())->SetMessageText(str);
//((CMainFrame *)GetParent())->GetMessageBar()->SetWindowText(str);

 CView::OnMouseMove(nFlags, point);
}
///

程序启动画面
VS2008中貌似无法插入Splash Screen组件
我准备尝试用AnimateWindow API自己来做
待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值