Posts Tagged MFC

经过重写的托盘图标CTray类

重写CTray缘于最近在写的某个Project。此Project需要显示托盘,所以我自然而然的想到了重用以前写的CTray。

但是当我把CTray文件添加到工程时,发现之前在编写CTray时,考虑得不够周到,整个类设计的也有问题

比如:强制使用带参数的constructor、成员函数命名不规范和异常情况考虑不周等问题

于是打算将CTray重写一遍,由于前后风格(命名风格请参考:匈牙利命名法的衰落和建议)和设计思维的改变,原有的代码几乎被推倒重写了一遍。

嗯,于是写了一天,终于完成。

现在的头文件大概是酱紫的

/**************************************************

** Project:CTray Design

** File:Tray.h

** Edition:v1.0.0 Demo

** Coder:KingsamChen [MDSA Group]

** Last Modify:2010-5-3

**************************************************/

#pragma once

#define WM_MY_TRAY  (WM_USER + 10)

class CTray : public CObject
{
	public:
		CTray();
		CTray(UINT trayId, UINT message);
		virtual	~CTray();

	public:
		LRESULT OnTrayProc(WPARAM wParam, LPARAM lParam);
		BOOL Create(CWnd* pWnd, HICON hIcon);
		BOOL Create(UINT trayId, UINT message, CWnd* pWnd, HICON hIcon);
		BOOL Show(LPCTSTR pszTipText);
		void Delete();
		BOOL Change(HICON hIcon, LPCTSTR pszTipText);
		BOOL ShowBalloonTip(LPCTSTR pszInfoTitle, LPCTSTR pszInfo,
							UINT timeout, DWORD infoFlags);
		virtual void AssertValid() const;

	public:
		static UINT ms_taskbarCreateMsg;

	protected:
		NOTIFYICONDATA m_Nid;
};

唔,做几点说明吧:

1.显然,这个类还是为MFC设计的(WTL似乎也可以经过少量修改后直接使用),纯SDK的话需要大规模重写( ̄ε(# ̄)

2.支持原来的功能:显示/修改/删除图标,集成Message Proc,支持任务栏重建时恢复,气泡风格

3.原有接口几乎全被破坏- -||,所以就有代码需要更新。

4.另外,重写时翻文档发现了一点东西:

WinVista后,由于Tray Icon的UI做了大量修改,很多属性都不推荐使用,比如NOTIFYICONDATA.uTimeout。并且新增了一些成员(包括之前文档标识为Reserved)。

气泡弹出的效果也做了改进(不使用uTimeout,转而使用其他新增加成员)

但是考虑到功能统一,并没有使用新增加的效果,有兴趣的自己修改CTray

PS:新文档参考:http://msdn.microsoft.com/en-us/library/bb762159%28VS.85%29.aspx

新版本的CTray下载地址:http://cid-cb24c6c6cbd98991.office.live.com/self.aspx/Blog%20File%20Storage/CTray%20Design.zip

, , , , ,

No Comments

在写ID Fighter中碰到的一些问题

RT,算是一些问题和经验的汇总吧

1、如何设置STATIC控件的背景色

在ID Fighter中,每个Player的每个属性都有一个相应的状态条,而这个状态条则是利用STATIC模拟而成

这就需要对STATIC进行背景颜色设置

但是,如果仅仅简单的在对话框的OnCtrlColor函数中利用pDC->SetBKColor进行绘制,得到的结果很难令人满意。

因为通过这种方法得到的背景色和文字量有关,也就是说,文字有几个,背景有多长。

如果我们需要设置整个控件的背景色,则需要通过如下的方法

HBRUSH hbrRed = ::CreateSolidBrush(RGB(255, 0, 0));

case IDC_LBLPLAYER1HPSTATUS:
case IDC_LBLPLAYER2HPSTATUS:
	pDC->SetBkColor(RGB(255, 0, 0));
	return hbrRed;

我们需要创建一个新的刷子,里用刷子来绘制背景色

2、GetWindowRect和ScreenToClient

由于需要对HP_Status_bar进行动态的调整,所以需要调整控件(窗体)的大小。MFC没有像.NET那样封装所谓的Width、Height属性,所以需要我们利用API来完成

但是当我用SetWindowPos来设置状态条时,状态条老是乱跑……和我自己预想的情况完全不同,而我又能确保缩放的算法是正确的

于是我把焦点放在了GetWindowRect中,仔细阅读MSDN之后,发现了一点

The GetWindowRect function retrieves the dimensions of the bounding rectangle of the specified window. The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.

GetWindowRect返回的矩形区域是基于屏幕坐标,而我需要的是以Dialog为基准。这就不难解释为什么我用SetWindowPos设置时,状态条会乱跑
Read the rest of this entry »

, , , , , ,

No Comments

ID Fighter V1 Final

前天晚上开始动工,早上完工,由于校运会,一直拖到现在

最大的变化就是比上个版本变得花哨了

1:为每个属性都增加了一个状态条,而且血条会根据实际情况发生变化
2:为每个ID增加了一个头像。嗯,你没看错,头像是从WP里Copy过来的

如果说遗憾之处,可能就是游戏的核心算法没有发生改变了。估计是我对这类东西没有过哪怕太多的深入,所以是在没法相处能够更好的,更具有平衡性和可玩性的算法

不过话说回来,对于这种MUD来说,估计最大的乐趣是文字而不是游戏本身了

在Update的过程中碰到了一些问题,也有了一些收获,具体会在另外的文章来说明~

Download ID Fighter V1 Final SRC_BIN

, , , ,

No Comments

浅析VC.NET的CString类

对于使用MFC的Coder来说,CString肯定是一个经常要用到的类,它封装了一个字符串应具有的大部分功能,使得MFC的字符串操作不像C中那么痛苦。

而文本旨在通过对CString类源代码的一些分析,使得大家对于这个类具有更深入的了解,避免在以后使用过程中出错。

在进入正题前,要说点题外话:为什么是VC.NET的CString类?

答案很简单,在M$将MFC从4.X(VC6)升级到7.X(VC.NET)开始,原来的CString被重新设计以便与ATL共用,并且支持了template特性。而由于VC6对于C++标准支持差得令人发指,成为众矢之的,且逐渐式微,将成明日黄花,故这里分析VC.NET的CString类

1. 亲子疑团之谁是我爹

在新的MFC体系中,CString并不是一个实际存在的类,实际上存在的是CSimpleStringT和CStringT,而我们常用的CString只是一个typedef-class。

这种变动,无疑让CString的身世显得扑朔迷离。

CString童鞋内牛满面,不禁高呼:你们到底谁TM是俺爹?

CString是谁呢?呃,在经过一番从CString到它祖宗十八代的调查后,我们发现:CString的爹,其实是CSimpleStringT。而CStringT,则是CString的前世

2.亲子疑团之混乱的关系

CSimpleString是CString体系变化的一个代表。

在过去,CString实际上是个独立的类,据说连万物之祖——CObject和它都没有半毛钱关系。CString一个人负责内存管理、字符串操作.etc

而到了新体系下,AFX小组为了更好地与ATL重用,将CString功能分拆成两块:基本的内存管理和缓存操作以及高级的字符串处理。CSimpleStringT便是负责前者。

至于CStringT,便继承自CSimpleStringT,然后封装了高级的字符串处理。

那么,我们为什么说CStringT是CString的前世呢?因为下面一行代码

typedef ATL::CStringT< TCHAR, StrTraitMFC< TCHAR > > CString;

对于采用了模板的类来说,这种typedef并不少见,std::string也是一个typedef-class

PS1:CStringT最初在ATL中设计,并有了MFC支持版(二者应该区别不大),于是编译器分别提供了cstringt.h和atlstr.h

PS2:即使是现在,CSimpleStringT也是独立的类,与CObject仍然没有半毛钱关系
Read the rest of this entry »

, , , , ,

No Comments

在C/C++中获取可执行文件的图标和信息

在写AutorunLoadViewer的过程中,需要能够获取可执行文件的图标和一些特定的文件信息(比如公司名还有文件版本.etc)

但是似乎MFC并没有提供现成的类库,于是只能自己通过API实现相应的功能

获取文件图标

关于如何获取文件图标,你可以很容易的在MSDN找到一个API——ExtracIcon

但是如果你仔细阅读文档说明,就会发现这个API并不符合我们的要求。因为ExtracIcon是从可执行文件的RC资源中找存在的图标,而不是返回在Win中显示的图标

所以,我们应该使用的API是SHGetFileInfo(关于这个API的详情,请自己查询相关文档)
Read the rest of this entry »

, , , , , ,

No Comments

AutorunLoadViewer BUG修正&部分重写

RT

BUG出现在未考虑可执行文件命令行中包含环境变量,导致获取文件路径不正确,启动项显示错误

之前没有想到这个情况,参考了大多数程序的自启动命令行,要么是全路径加参数,要么是纯命令行,而这种类型的注册表值类型(Value Type)都是REG_SZ。

直到装了新本本中小黑的某个管理程序,而这个程序的自启动命令行就包含了环境变量%ProgramFiles%。而这种类型的注册表值类型是REG_EXPAND_SZ

于是在之前的ARV中直接显示“文件不存在”

新版本修正了这个BUG,并且下载地址的文件也已经更新

今天给别人测试的时候发现拿路径的另一个BUG,现已解决。在此对ZZP和Leap.Ahead童鞋表示感谢

在最初修改代码的时候,打算采用switch,并且为三种情况分别设置一个PURE_COMMAND、NORMAL_COMMAND和ENVIRONMENTAL_COMMAND。但是很不幸的遗忘了switch中跳过Label声明局部变量会产生警告。而我又不愿意利用{}来设置有效域,于是改为采用if…else if….else

此次修正顺便改变了之前部分“丑陋”的代码,增加了对可执行文件的CheckIsExist过程,以及对于获取可执行文件信息代码的部分修正

Ok,that’s all

Download:AutorunLoadViewer_BIN_SRC

, , , , , ,

5 Comments

ID Fighter从Demo走向Beta

昨晚弄了弄,修缮了一下,可以当作Beta发行了

其实也没有什么大改进,主要就是

1:增加了MD5库,通过MD5对ID的名字进行计算比较。取代了Demo中直接的String Compare
    MD5来自腌菜童鞋,在此表示感谢

2:重构了部分代码,比如利用struct PlayerState代替原来一坨的直接属性

struct PlayerState
{
	CString sName;
	double dIniRate;
	int nHp, nHpMax;
	int nAttack;
	int nDefence;
	int nSwiftness;
	int nFortune;
};

	protected:
		PlayerState m_Id1State;
		PlayerState m_Id2State;
		CString m_sFightStr;
		CString* m_psLoser;	// pointer

UI上完全没什么变化,功能也没有增加,除了对PlayerName的处理发生了一些变化之外~

过后一段时间的Final版,会努力实现如下效果:

1:为Player生成随机头像
2:增加更多的招数
3:实现人物属性的状态槽

Beta版可以在这里下载:Download ID Fighter Beta

欢迎关注ID Fighter

, , , , ,

No Comments

如何在MFC设计超链接控件类

关于如何在MFC设计自己的超链接控件类,KC之前写过这样的文章。额,其实那篇文章也就一代码……而且代码质量有点烂

于是经过重修Rebuild之后,把设计的详细过程加以分析~


1.摘要

控件的超链接效果在程序的UI设计中是经常会碰到的。但是在MFC的低版本中(VS2008所对应的MFC 9之前的版本),并没有现成的控件可以使用(WTL在早期似乎就提供了类似的控件)。

什么?你说可以在STATIC控件的WM_MOUSEMOVE中修改鼠标指针达到目的?呃,这个想法非常好,这个思路可以马上解决问题。但是呢,呃,问题在于,STATIC控件默认是不接受WM_MOUSEMOVE消息的。

而这也是我们设计类的主要原因,我们可以稍稍动些手脚,至于具体,下面再说~

如果你需要这一效果,但是不想更新自己的IDE或者转而使用WTL,又或者你希望能够了解如何自己动手实现这一效果,那么此文可以为你提供一些帮助。


2. 我们需要什么?

在设计类CLabelLink之前,我们需要明确我们的需求。这是非常重要的一个过程,在SE中,这个步骤被华丽地称作“需求分析”

1:控件宿主

在现有的控件上进行二次开发是一个不错的选择,这样做可以避免需要自己设计一个ACTX控件的麻烦。

在现有的控件中,静态文本STATIC无疑是最好的选择。所以我们的类,将选择继承自CStatic。并且为了能够接受WM_MOUSEMOVE消息,我们需要添加相应的消息映射接口~
Read the rest of this entry »

, , , ,

6 Comments

ID Fighter V1 Demo

RT

这玩意儿写了3、4天吧,第一次用VC2008的MFC9写东西,感觉有点不适应~不过总体上还是和以前类似~(如果提示无法运行,请注意是否有必须的运行库)

ID Fighter是什么?

ID Fighter的中文名是ID斗士,但是我觉得他的英文名远比中文名要来的有魅力,这点如同KingsamChen要比陈XX来的帅

ID Fighter实际上来源于KC很久以前玩过的一款叫做ID打架的游戏。这款游戏原作是利用Flash进行设计和制作,玩家可以输入两个ID名字,然后通过PK的形式决出高低。

而这款ID Fighter可以说是ID打架的一个翻版( ̄ε(# ̄),具有相类似的功能

Read the rest of this entry »

, , , , , ,

3 Comments

AutorunLoadViewer V1 Beta

  从去年暑假开始折腾,一直折腾到现在,终于把他给Beta了,HIAHIA

  之前交给Lieo的那份是Demo的,而目前的这份Beta多了两个功能,显示Item的图标和公司信息。

  不过也就为了增加这两个功能,也着实浪费了我一点时间,主要是在增加功能的前提下,不能破坏原有的架构(其实就是增加了一个CQueryExeInfo的类罢了)。

  谢天谢地,这玩意儿终于让我KO了~终于可以对ARV实行烂尾手段了囧…

  似乎上次Lieo没有公开这部分的SRC。厄,不错没关系,自己看好了,鉴于篇幅原因(数了下,不包括.h的话,大约在1700±100 Rows左右),只放下新增加的代码。

/**************************************************

** Project:AutorunLoadViewer

** File:QueryExeInfo.h

** Edition:v1.0.0 Beta

** Coder:KingsamChen [MDSA Group]

** Last Modify:2010-2-18

**************************************************/

#pragma once

#pragma comment(lib, "version.lib")

class CQueryExeInfo : public CObject
{
	public:
		CQueryExeInfo();
		virtual ~CQueryExeInfo();
		HICON QueryExeIcon(LPCTSTR lpszExePath);
		static void FreeIconBuffer(HICON hIcon);
		void QueryExeCompanyName(LPCTSTR lpszExePath, CString& sCompanyName);

	protected:
		DWORD GetExeVersionInfo(LPCTSTR lpszExePath);
		void FreeVersionBuffer();

	protected:
		LPVOID m_lpVersionBuffer;
		LPVOID m_szCompanyName;
};

Read the rest of this entry »

, , , , ,

3 Comments