SkinSB皮肤滚动条库的使用

SkinSB皮肤滚动条库的使用_第1张图片 

说明
     SkinSB库能为Windows标准控件或制定控件设置自定义滚动条皮肤,从而去达到美化控件的目的,如果觉得原Windows滚动条样式无法与你的程序界面搭配的话,那么SkinSB能帮你轻松的完成滚动条皮肤问题。该源代码为C语言编译通过,以标准API调用规范导出来函数,因此它可以在其它语言中使用,只需要将静态连接库改为动态链接库即可。

 

作者 : 李俊

E-Mail : [email protected]  QQ : 154828

 

历史修订(V1.2)

2008-12-24
修正了RichEdit控件在拖动滑块时滑块没有反应的问题。

2009-05-20
修正了滚动条滑块在拖动时闪烁的问题。

2009-09-21
1.修正了RichEidt设置皮肤滚动条后即使RichEdit中没有内容仍显示有滑块的问题。
2.修正了无滑块时点击箭头时箭头被背景复盖的问题。
3.修改了皮肤资源便于绘制时计算位图资源坐标。
4.修正了水平滚动条箭头按下无法弹起的问题。
5.修正了窗口在不活动状态时滑块显示不出来的问题。

 

下载地址(V1.0):http://download.csdn.net/source/1013411

下载地址(V1.2):http://download.csdn.net/source/1712097

 

使用说明

    首先你要确定的是你的控件是一个Windows控件还是一个自定义控件,如果是一个Windows控件那么就必须在程中去使用Detours库,这个库的功能就是截获指定的API函数并将这个API参数传递给你自已的函数处理,因为要绘制滚动条必须先获得滚动信息,由于Windows控件设置滚动信息是由系统完成的,所以就必须使用Detours获取滚动信息。有关Detours的技术资料请访问:http://research.microsoft.com/en-us/projects/detours/

 

下面就以MFC工程的Windows控件作为示例

 

1.首先将下列文件加入工程:

#include "detours.h" #include "skinsb.h" #pragma comment(lib, "detours.lib") #pragma comment(lib, "skinsb.lib")

2.设置Detours截获系统设置的滚动信息传递给SkinSB

 

申明HOOK API
DETOUR_TRAMPOLINE(int WINAPI SetScrollInfoT(HWND, int, LPCSCROLLINFO, BOOL), SetScrollInfo) DETOUR_TRAMPOLINE(BOOL WINAPI GetScrollInfoT(HWND, int, LPSCROLLINFO), GetScrollInfo) DETOUR_TRAMPOLINE(int WINAPI SetScrollPosT(HWND, int, int, BOOL), SetScrollPos) DETOUR_TRAMPOLINE(int WINAPI GetScrollPosT(HWND, int), GetScrollPos) DETOUR_TRAMPOLINE(BOOL WINAPI GetScrollRangeT(HWND, int, LPINT, LPINT), GetScrollRange) DETOUR_TRAMPOLINE(BOOL WINAPI SetScrollRangeT(HWND, int, int, int, BOOL), SetScrollRange) DETOUR_TRAMPOLINE(BOOL WINAPI ShowScrollBarT(HWND, int, BOOL), ShowScrollBar) DETOUR_TRAMPOLINE(BOOL WINAPI EnableScrollBarT(HWND, UINT, UINT), EnableScrollBar)

将HOOK到的函数的参数传递到SkinSB函数中

int WINAPI SetScrollInfoD(HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, BOOL bRedraw) { if( SkinSB_IsValid(hwnd) ) return SkinSB_SetScrollInfo(hwnd, fnBar, lpsi, bRedraw); else return SetScrollInfoT(hwnd, fnBar, lpsi, bRedraw); } BOOL WINAPI GetScrollInfoD(HWND hwnd, int fnBar, LPSCROLLINFO lpsi) { if( SkinSB_IsValid(hwnd) ) return SkinSB_GetScrollInfo(hwnd, fnBar, lpsi); else return GetScrollInfoT(hwnd, fnBar, lpsi); } int WINAPI SetScrollPosD(HWND hwnd, int nBar, int nPos, BOOL bRedraw) { if( SkinSB_IsValid(hwnd) ) return SkinSB_SetScrollPos(hwnd, nBar, nPos, bRedraw); else return SetScrollPosT(hwnd, nBar, nPos, bRedraw); } int WINAPI GetScrollPosD(HWND hwnd, int nBar) { if( SkinSB_IsValid(hwnd) ) return SkinSB_GetScrollPos(hwnd, nBar); else return GetScrollPosT(hwnd, nBar); } BOOL WINAPI SetScrollRangeD(HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL bRedraw) { if( SkinSB_IsValid(hwnd) ) return SkinSB_SetScrollRange(hwnd, nBar, nMinPos, nMaxPos, bRedraw); else return SetScrollRangeT(hwnd, nBar, nMinPos, nMaxPos, bRedraw); } BOOL WINAPI GetScrollRangeD(HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos) { if( SkinSB_IsValid(hwnd) ) return SkinSB_GetScrollRange(hwnd, nBar, lpMinPos, lpMaxPos); else return GetScrollRangeT(hwnd, nBar, lpMinPos, lpMaxPos); } BOOL WINAPI ShowScrollBarD(HWND hwnd, int nBar, BOOL bShow) { if( SkinSB_IsValid(hwnd) ) return SkinSB_ShowScrollBar(hwnd, nBar, bShow); else return ShowScrollBarT(hwnd, nBar, bShow); } BOOL WINAPI EnableScrollBarD(HWND hwnd, UINT wSBflags, UINT wArrows) { if( SkinSB_IsValid(hwnd) ) return SkinSB_EnableScrollBar(hwnd, wSBflags, wArrows); else return EnableScrollBarT(hwnd, wSBflags, wArrows); }

加载API HOOK的代码,最好写在CXXXApp::InitInstance()函数中
DetourFunctionWithTrampoline((PBYTE)SetScrollInfoT, (PBYTE)SetScrollInfoD); DetourFunctionWithTrampoline((PBYTE)GetScrollInfoT, (PBYTE)GetScrollInfoD); DetourFunctionWithTrampoline((PBYTE)SetScrollPosT, (PBYTE)SetScrollPosD); DetourFunctionWithTrampoline((PBYTE)GetScrollPosT, (PBYTE)GetScrollPosD); DetourFunctionWithTrampoline((PBYTE)SetScrollRangeT, (PBYTE)SetScrollRangeD); DetourFunctionWithTrampoline((PBYTE)GetScrollRangeT, (PBYTE)GetScrollRangeD); DetourFunctionWithTrampoline((PBYTE)ShowScrollBarT, (PBYTE)ShowScrollBarD); DetourFunctionWithTrampoline((PBYTE)EnableScrollBarT, (PBYTE)EnableScrollBarD);

 卸载API HOOK,最好写在CXXXApp::ExitInstance()函数中
DetourRemove((PBYTE)SetScrollInfoT, (PBYTE)SetScrollInfoD); DetourRemove((PBYTE)SetScrollPosT, (PBYTE)SetScrollPosD); DetourRemove((PBYTE)GetScrollInfoT, (PBYTE)GetScrollInfoD); DetourRemove((PBYTE)GetScrollPosT, (PBYTE)GetScrollPosD); DetourRemove((PBYTE)SetScrollRangeT, (PBYTE)SetScrollRangeD); DetourRemove((PBYTE)GetScrollRangeT, (PBYTE)GetScrollRangeD); DetourRemove((PBYTE)ShowScrollBarT, (PBYTE)ShowScrollBarD); DetourRemove((PBYTE)EnableScrollBarT, (PBYTE)EnableScrollBarD);

 3.在窗口初始化时为控件设置滚动条皮肤

BOOL CSkinSBDemoDlg::OnInitDialog() { CDialog::OnInitDialog(); //装入位图 m_bmScroll.LoadBitmap(IDB_SCROLL); //为控件设置滚动条皮肤 SkinSB_Init(GetDlgItem(IDC_LIST1)->GetSafeHwnd(), m_bmScroll); SkinSB_Init(GetDlgItem(IDC_EDIT1)->GetSafeHwnd(), m_bmScroll); return TRUE; } 

      以上代码就完成了针对Windows控件设置滚动条皮肤的工作,是不是很简单?那么怎样为自定义控件设置滚动条皮肤呢,其实你也可以用以上的方法为你的自定义控件设置滚动条皮肤,好处就是方便,坏处也是有的那就是要在工程中使用Detours库,虽然Detours体积不算大但是考虑到程序的效率和代码的简洁性宁原不使以Detours库。那么如何为自定义控件设置滚动条皮肤呢?SkinSB里导出了滚动条API函数,它的函数原型与Windows Scrollbar API是一样的,只不过每个函数前都有个SkinSB_XXX原因是不和Windows命名的API发生冲突,下面来看下这些函数的说明:

//------------------------------------------------------------------------------ // 函数名称: // SkinSB_Init // 参数: // - HWND hwnd 指定一个需要加载皮肤滚动条的窗口句柄 // - HBITMAP hBmp 指定一个位图句柄,滚动条皮肤位图 // 反回: // BOOL 如果函数成功反回一个非零值,否则反回为零 // 说明: // 初始化并给指定的控件加载滚动条皮肤 //------------------------------------------------------------------------------ BOOL WINAPI SkinSB_Init(HWND hwnd,HBITMAP hBmp); //------------------------------------------------------------------------------ // 函数名称: // SkinSB_Uninit // 参数: // - HWND hwnd 指定一个需要移除滚动条皮肤的窗口句柄 // 反回: // BOOL 如果函数成功反回一个非零值,否则反回为零 // 说明: // 移除窗口的滚动条皮肤,还原系统样式的滚动条 //------------------------------------------------------------------------------ BOOL WINAPI SkinSB_Uninit(HWND hwnd); //------------------------------------------------------------------------------ // 函数名称: // SkinSB_IsValid // 参数: // - HWND hwnd 指定一个窗口句柄 // 反回: // BOOL 如果函数成功反回一个非零值,否则反回为零 // 说明: // 确定一个窗口是否加载了皮肤滚动条 //------------------------------------------------------------------------------ BOOL WINAPI SkinSB_IsValid(HWND hwnd); //------------------------------------------------------------------------------ // 函数名称: // SkinSB_GetScrollInfo // 参数: // - HWND hwnd 指定一个窗口句柄 // - int fnBar 指示是一个水平还是垂直的滚动条 // - LPSCROLLINFO lpsi 指向滚动条滚动信息结构体指针 // 反回: // BOOL 如果函数成功反回一个非零值,否则反回为零 // 说明: // 获得滚动条的滚动信息参数 //------------------------------------------------------------------------------ BOOL WINAPI SkinSB_GetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi); //------------------------------------------------------------------------------ // 函数名称: // SkinSB_SetScrollInfo // 参数: // - HWND hwnd 指定一个窗口句柄 // - int fnBar 指示是一个水平还是垂直的滚动条 // - LPSCROLLINFO lpsi 指向滚动条滚动信息结构体指针 // - BOOL fRedraw 是否重绘滚动条,如果为真则重绘滚动条 // 反回: // int 如果函数成功则反回滚动条滑块当前位置 // 说明: // 设置滚动条的滚动信息参数 //------------------------------------------------------------------------------ int WINAPI SkinSB_SetScrollInfo(HWND hwnd, int fnBar, LPCSCROLLINFO psi, BOOL fRedraw); //------------------------------------------------------------------------------ // 函数名称: // SkinSB_GetScrollPos // 参数: // - HWND hwnd 指定一个窗口句柄 // - int fnBar 指示是一个水平还是垂直的滚动条 // 反回: // int 如果函数成功则反回滚动条滑块当前位置 // 说明: // 获得滚动滑块当前位置 //------------------------------------------------------------------------------ int WINAPI SkinSB_GetScrollPos(HWND hwnd, int fnBar); //------------------------------------------------------------------------------ // 函数名称: // SkinSB_SetScrollPos // 参数: // - HWND hwnd 指定一个窗口句柄 // - int fnBar 指示是一个水平还是垂直的滚动条 // - int nPos 指定一个期望的滚动条滑块位置 // - BOOL fRedraw 是否重绘滚动条,如果为真则重绘滚动条 // 反回: // int 如果函数成功则反回期望的滚动条滑块位置 // 说明: // 设置滚动条滑块期望的位置 //------------------------------------------------------------------------------ int WINAPI SkinSB_SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL fRedraw); //------------------------------------------------------------------------------ // 函数名称: // SkinSB_GetScrollRange // 参数: // - HWND hwnd 指定一个窗口句柄 // - int fnBar 指示是一个水平还是垂直的滚动条 // - LPINT lpMinPos 指向一个int变量的指针,反回滚动条最小范围值 // - LPINT lpMaxPos 指向一个int变量的指针,反回滚动条最大范围值 // 反回: // BOOL 如果函数成功反回一个非零值,否则反回为零 // 说明: // 获得滚动条滚动范围值 //------------------------------------------------------------------------------ BOOL WINAPI SkinSB_GetScrollRange(HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos); //------------------------------------------------------------------------------ // 函数名称: // SkinSB_SetScrollRange // 参数: // - HWND hwnd 指定一个窗口句柄 // - int fnBar 指示是一个水平还是垂直的滚动条 // - int nMinPos 指定一个最小范围值 // - int nMaxPos 指定一个最大范围值 // - BOOL fRedraw 指示是否立即进行重绘,TRUE立即重绘FALSE不立即重会 // 反回: // BOOL 如果函数成功反回一个非零值,否则反回为零 // 说明: // 设置滚动条滚动范围值 //------------------------------------------------------------------------------ BOOL WINAPI SkinSB_SetScrollRange(HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw); //------------------------------------------------------------------------------ // 函数名称: // SkinSB_ShowScrollBar // 参数: // - HWND hwnd 指定一个窗口句柄 // - int fnBar 指示是一个水平还是垂直的滚动条 // - BOOL fShow 指示是否显示或隐藏滚动条,TRUE则显示滚动条FALSE则隐藏滚动条 // 反回: // BOOL 如果函数成功反回一个非零值,否则反回为零 // 说明: // 显示或隐藏滚动条 //------------------------------------------------------------------------------ BOOL WINAPI SkinSB_ShowScrollBar(HWND hwnd, int wBar, BOOL fShow); //------------------------------------------------------------------------------ // 函数名称: // SkinSB_EnableScrollBar // 参数: // - HWND hwnd 指定一个窗口句柄 // - UINT wSBflags 指示是一个水平还是垂直的滚动条或两个同时 // - UINT wArrows 指示禁止或启用哪些箭头按钮 // 反回: // BOOL 如果函数成功反回一个非零值,否则反回为零 // 说明: // 禁用或启用滚动条箭头按钮 //------------------------------------------------------------------------------ BOOL WINAPI SkinSB_EnableScrollBar(HWND hwnd, UINT wSBflags, UINT wArrows); 
      以上这些API用法跟Windows Scrollbar API用法是一样的,只不过多了前面三个函数。有了以上这些函数你就可以为自定义控件设置滚动信息,别忘了用SkinSB_Init来加载皮肤位图,要注意的是要加载的皮肤位图规格必须与Demo中的相同,否则画出来的将是一团糟。最后一点要说明的是这个SkinSB库不能够为ScrollBar控件本身设置皮肤,如果有这样需要可以拿源代码自已改即可。

 

好了我就不多说了,如果文章和代码有不当之处不请P正,有什么建议或者问题请联系我!

你可能感兴趣的:(界面/图形)