如何在VC中使用自定义的SkinMagic控件?

news/2024/6/18 5:48:51
 在SkinMagic中自定义了一个控件皮肤,并且添加到皮肤文件(.smf);但是,如何在vc程序中使用它呢?本文以CSplitterWnd为例子,说明使用方法。

我想对分割条类CSplitterWnd设计皮肤,SkinMagic没有提供该标准控件;于是,我自定义了该控件。

控件皮肤类型名叫:"SkinSplitter",三个主要属性:

SplitterBar:IMAGERECT类型

Border:IMAGESETION类型

Gripper:IMAGESETION类型

并在皮肤文件中添加了该对象,对象名为"SkinSplitter"。

如图:

现在说说在程序中使用方法,假设我们已经将皮肤文件载入程序,我们重载CSplitterWnd的类名叫CXSplitterWnd。

1、注册控件皮肤对象

重载CSplitterWnd::OnCreate(),然后调用RegisterSkinWindow(m_hWnd,0):

int CXSplitterWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CSplitterWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
 
    RegisterSkinWindow(m_hWnd, 0);
 
    return 0;
}

2、控件销毁时,反注册控件皮肤对象

重载CSplitterWnd::OnDestroy(),然后调用UnregisterSkinWindow和CloseSkinData:

void CXSplitterWnd::OnDestroy()
{
    CSplitterWnd::OnDestroy();
 
    UnregisterSkinWindow(m_hWnd);
    CloseSkinData(m_hSkin);// m_hSkin是在CXSplitterWnd添加的HSKIN类型成员
}

3、添加消息WM_SKINDATACHANGED的响应函数

WM_SKINDATACHANGED是SkinMagic SDK自定义的消息,表示皮肤数据发生改变。编写消息响应函数请读者自行查找,很方便的。:)

我们定义该消息响应函数为OnSkinDataChanged;在其中载入皮肤文件中的对象SkinSplitter:

LRESULT CXSplitterWnd::OnSkinDataChanged(WPARAM wParam, LPARAM lParam)
{
 if( m_hSkin ) CloseSkinData( m_hSkin );

 m_hSkin = OpenSkinData("SkinSplitter");// 皮肤文件中的自定义皮肤对象
 if( m_hSkin )
 {
  RedrawWindow();
 }
 return 1;
}

4、调用DrawSkinImageRect、DrawSkinImageSetion等方法重绘分割条

我采取的方法是重载CSplitterWnd::OnPaint(),在其中重绘分割条:

void CXSplitterWnd::OnPaint()

{

    ......

   // rectSplitter是分割条的真实方形区域

   // 获取分割条的真实方形区域的方法请看我的另一篇文章"如何获取分割条的真实RECT? "

  DrawSkinImageRect(m_hSkin, _T("SplitterBar"), dc, &rectSplitter); // 根据皮肤对象SkinSplitter属性SplitterBar重绘
  DrawSkinImageSection(m_hSkin, _T("Border"), dc, &rectSplitter); // 根据皮肤对象SkinSplitter属性Border重绘
  DrawSkinImageSection(m_hSkin, _T("Gripper"), dc, &rectSplitter); // 根据皮肤对象SkinSplitter属性Gripper重绘

}

到此结束!

其他自定义控件的使用方法大致相同,只是在重载的函数上可能不同。

希望能帮到大家,:)

 

 

是不是想重画分割条,但是用CSplitterWnd::GetRect(...)方法获取后,发现不对呢?这里教你如何获取分割条真实的方形区域。

假如你的分割条类型是CMySplitterWnd(继承自CSplitterWnd),对象是m_Splitter,则 m_Splitter.GetRect(rect)获得的方形区域实际上是整个分割窗口的方形区域。如果想获得分割条的RECT,就得自己计算。方法如 下:

//(假设我们重载了CSplitterWnd::OnPaint())

void CMySplitterWnd::OnPaint()
{
    CPaintDC dc(this); // device context for painting

    int iColumn = 0;
    int iRow = 0;
    RECT rect1, rect2, rectSplitter;

    // 获取每一个垂直的分割条的RECT

    for (iColumn=1; iColumn<GetColumnCount(); iColumn++)
    {
        GetPane(0, iColumn-1)->GetWindowRect(&rect1);
        GetPane(GetRowCount()-1, iColumn)->GetWindowRect(&rect2);

        rectSplitter.top = rect1.top;
        rectSplitter.bottom = rect2.bottom;
        rectSplitter.right = rect2.left;
        rectSplitter.left = rect1.right;

        ScreenToClient(&rectSplitter);
       // ... do what u want to do!

    }

    // 获取每一个水平的分割条的RECT

    for (iRow=1; iRow<GetRowCount(); iRow++)
    {
        GetPane(iRow-1, 0)->GetWindowRect(&rect1);
        GetPane(iRow, GetColumnCount()-1)->GetWindowRect(&rect2);

        rectSplitter.top = rect1.bottom;
        rectSplitter.bottom = rect2.top;
        rectSplitter.right = rect2.right;
        rectSplitter.left = rect1.left;

        ScreenToClient(&rectSplitter);
        // ...do what u want to do!
     }
}

 

也有另外一种办法,就是用WTL7.1中的CSplitterWindowImpl类。它的成员函数GetSplitterBarRect(...)可以直接获得,但是WTL7.1只能支持Windows2000及XP以上的系统,对于开发商业产品,使不合适的。


http://www.niftyadmin.cn/n/3337890.html

相关文章

ASP.Net下两种全局变量的设置和读取方法

本文介绍两种ASP.Net项目中全局变量使用的方式。web.config文件 和 Gloab文件。以下分别说明&#xff1a;方法一&#xff1a;web.config文件——设置&#xff1a;在web.config文件里添加关键字key是通过<appSettings>标记来实现的&#xff0c;但是appSettings标记通常放在…

基本的python语法知识_python_基础知识_安装和基础语法

一.python安装先在官网&#xff0c;找到所属系统的安装环境。建议选择3.x建议选择安装稳定版本。选择自行配置安装环境。直接选择Next&#xff0c;进行下一步。选择安装目录。安装页面&#xff0c;等待安装。安装完成&#xff0c;点击‘Close’在开始中&#xff0c;搜索框中输入…

linux中ip修改,Linux中修改IP

现在正在复习linux&#xff0c;将一些比较常用的东西记下来&#xff0c;一遍以后再次复习使用root用户登录&#xff0c;或者用普通用户登录之后使用su root切换&#xff0c;相信正常人都会选择前者。1、切换目录&#xff1a;cd /etc/sysconfig/network-scripts2、使用vi编辑器…

三十而立如何成为准富人

作者&#xff1a; 尹娟 来源&#xff1a; 第一理财网 发表时间&#xff1a; 2008-07-15 从三十而立&#xff0c;到三十而富&#xff0c;社会给予了三十岁这个年龄众多的含义。这几年正值第一代独生子女逐步迈入三十岁这道年龄坎&#xff0c;对于颇具有时代烙印的这一代人来说…

Effective C# 原则7: 选择恒定的原子值类型数据(译)

Effective C# 原则7&#xff1a; 选择恒定的原子值类型数据Prefer immutable automic value type 恒定类型(immutable types)其实很简单&#xff0c;就是一但它们被创建&#xff0c;它们(的值)就是固定的。如果你验证一些准备用于创建一个对象的参数&#xff0c;你知道它在验证…

如何将两个微信小程序合并_微信小程序--如何在两个页面之间传值

先看一下本周的部分的设计图在这里插入图片描述在这里插入图片描述在这里插入图片描述页面设计并不太复杂&#xff0c;主要是产品类型那块点击的样式&#xff0c;其余的都不太复杂&#xff0c;没啥好说的。这次主要是想记录一下不同页面下的传值你看&#xff0c;在这个出发城市…

[分享]总结:VC小知识!-1

&#xff08;1&#xff09; 如何通过代码获得应用程序主窗口的 指针?主窗口的 指针保存在CWinThread::m_pMainWnd中,调用AfxGetMainWnd实现。AfxGetMainWnd() ->ShowWindow(SW_SHOWMAXMIZED)//使程序最大化. &#xff08;2&#xff09; 确定应用程序的路径Use GetModuleFi…

linux 错误信息 输出到管道,Linux管道只传到错误信息(stderr)——从一个小问题写起...

碰到问题在自己编写的一个小脚本中&#xff0c;碰到这个一个小问题&#xff1a;问题背景&#xff1a;在脚本中多次导出数据&#xff0c;为了不用重复输入密码&#xff0c;在运行时&#xff0c;使用read读取用户输入&#xff0c;将密码存入变量。将mysql的命令中使用该变量&…