当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 让你的软件界面更漂亮(三)

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 让你的软件界面更漂亮(三)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 103 ::
收藏到网摘: n/a

让你的软件界面更漂亮(三)

作者:朱一松

下载源代码

  实现令人满意的风格统一的软件界面确实很难, 象网友提到的MessageBox、FileDialog、FontDialog、目录选择对话框等MFC内部甚至系统DLL内的对话框,要想让它变脸可不容易。有人说HOOK技术可以,HOOK技术确实可以,HOOK可以说是无孔不入,但HOOK的使用效率却是令人难以满意的,从目前大多数采HOOK技术的换肤软件使用情况来看,完全可以证明这一点。今天我们将讨论另外一技术来实现FileDialog的变脸,这种技术叫替换窗口过程法(注:本人杜撰)。
  窗口过程函数是大多窗口都有的,它处理窗口中(包括子窗口)的每一个事件,替换窗口过程法与HOOK技术比起来孰强誰弱是很显然的,因为同一个HOOK只能拦截一个事件,处理起来相当费时,HOOK也有它的优势,但不是本文要讨论的。这里先让大家眼见为实,请看下图:
       
一、原理说明:
替换对话框的窗口过程要用到这个函数SetWindowLong()其原型如下:

LONG SetWindowLong(HWND hWnd, int nIndex , long dwLongNewProc)hWnd为指定窗口的句柄,nIndex 为 GWL_WNDPROC时才可设定新的窗口过程dwLongNewProc 为指定新的窗口过程函数地址 
反回值为一个long的数值,此值为旧的窗口过程函数地址。
如果要替换某个窗口的窗口过程函数,首先要想法弄到它的窗口的句柄,当然还得有窗口过程。

二、CFileDialog文件对话框界面设计
a. 从CFileDialog派生类CMyFileDialog;
b. 添加Protected 型虚成员函数:OnInitDone();
此函是实际上是CFileDialog一个虚函数,它在文件对话框创后建后被调用,它给我们留下了一个入口,因些重载现实替换其窗口过程函数;
c. 添加成员函数MyWindowProcNew()
static LRESULT CALLBACK WindowProcNew(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);	
在这函数实现的时候你可大显身手,处理得好不好决定你是否能变脸成功。d. 实现代码及说明如下:
WNDPROC m_MyWndProc; //定义全局变量保存旧的窗口过程函数地址void CMyFileDialog::OnInitDone(){	CWnd* pDialog = GetParent();	m_MyWndProc=(WNDPROC)SetWindowLong(pDialog->m_hWnd,GWL_WNDPROC,(long)MyWindowProcNew);}LRESULT CALLBACK CMyFileDialog::MyWindowProcNew(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){	switch (message)	{	case WM_NOTIFY:	case WM_MOUSEMOVE:	case WM_MOVE:	break;	case WM_NCACTIVATE:	break;	case WM_NCPAINT:	break;	case WM_NCMOUSEMOVE:	break;	case WM_PAINT:	break;	case WM_COMMAND:	break;	case WM_SIZE:	break;	case WM_XX:	default:	break;	}	//这时要恢复调用旧的窗口函数,当然必时可要忽略它	return CallWindowProc(m_MyWndProc, hwnd, message, wParam, lParam);}
  这个函数CallWindowProc()用来恢调用复旧窗口过程函数,当然这并不意味取消了新的窗口过程。你也可跳过它不去执行,那为什要恢复旧的窗口过程函数?因为旧的窗口过程函数它处理了太多的事件,而新窗口过程函数只处理我们关心的事件,如果你乐意的话你完全可不要调用旧的窗口过程函数,那可是要付出大的代价的。具体细节请大家去实现,可参“让你的软件界面更漂亮(一)”。

三、CMyFileDialog的用法
  我把CMyFileDialog写成一个DLL,有Debug和Release两个版,请用时分别选择a.先把.lib .dll .h 文件持拷到工程目录。在要使用处加如代码:
#include "MyFileDialg.h"#pragam comment(lib,"user.lib")
b.显示文件对话框:
 CMyFileDialog MyFileDlg(TRUE, 1, _T("对话框标题")); MyFileDlg.DoModal(); CString FileName = MyFileDlg.GetPathName() FileName是反回的结果
c. CMyFileDialog有一个超值的功能,不知有没有从上图看出来?它能够用来代替 SHBrowseForFoler 作为目录选择对话框。这也是我写CMyFileDialog的初终。构造函数第一个参数和CfileDialg 一样,第二个参数为TRUE时可作为目录选择 对话框, 此时第一个参数可BOOL的任意值建议设为TRUE,第三个参数为对话框标题,如为NULL则显示默认标题,其它参数和CFileDialog一样。

欢迎指正! 本人的联系QQ:34544052 Email:[email protected]