Posts Tagged MFC
经过重写的托盘图标CTray类
Posted by kingsamchen in PROGRAMMING on 2011 年 05 月 03 日
重写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
在写ID Fighter中碰到的一些问题
Posted by kingsamchen in PROGRAMMING on 2010 年 10 月 24 日
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 »
ID Fighter V1 Final
Posted by kingsamchen in PROGRAMMING on 2010 年 10 月 23 日
前天晚上开始动工,早上完工,由于校运会,一直拖到现在
最大的变化就是比上个版本变得花哨了
1:为每个属性都增加了一个状态条,而且血条会根据实际情况发生变化
2:为每个ID增加了一个头像。嗯,你没看错,头像是从WP里Copy过来的
如果说遗憾之处,可能就是游戏的核心算法没有发生改变了。估计是我对这类东西没有过哪怕太多的深入,所以是在没法相处能够更好的,更具有平衡性和可玩性的算法
不过话说回来,对于这种MUD来说,估计最大的乐趣是文字而不是游戏本身了
在Update的过程中碰到了一些问题,也有了一些收获,具体会在另外的文章来说明~
浅析VC.NET的CString类
Posted by kingsamchen in PROGRAMMING on 2010 年 08 月 26 日
对于使用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 »
在C/C++中获取可执行文件的图标和信息
Posted by kingsamchen in PROGRAMMING on 2010 年 08 月 12 日
在写AutorunLoadViewer的过程中,需要能够获取可执行文件的图标和一些特定的文件信息(比如公司名还有文件版本.etc)
但是似乎MFC并没有提供现成的类库,于是只能自己通过API实现相应的功能

获取文件图标
关于如何获取文件图标,你可以很容易的在MSDN找到一个API——ExtracIcon
但是如果你仔细阅读文档说明,就会发现这个API并不符合我们的要求。因为ExtracIcon是从可执行文件的RC资源中找存在的图标,而不是返回在Win中显示的图标
所以,我们应该使用的API是SHGetFileInfo(关于这个API的详情,请自己查询相关文档)
Read the rest of this entry »
AutorunLoadViewer BUG修正&部分重写
Posted by kingsamchen in PROGRAMMING on 2010 年 08 月 11 日
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
ID Fighter从Demo走向Beta
Posted by kingsamchen in PROGRAMMING on 2010 年 07 月 19 日
昨晚弄了弄,修缮了一下,可以当作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
如何在MFC设计超链接控件类
Posted by kingsamchen in PROGRAMMING on 2010 年 07 月 01 日
关于如何在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 »
ID Fighter V1 Demo
Posted by kingsamchen in PROGRAMMING on 2010 年 06 月 22 日
AutorunLoadViewer V1 Beta
Posted by kingsamchen in PROGRAMMING on 2010 年 02 月 18 日
从去年暑假开始折腾,一直折腾到现在,终于把他给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;
};


COMMENTS