我的书房 我的天地

129 views 十二月 04, 06 by Timothy

我的书房。
我常常在这间屋子呆到深夜。
可以静静的坐在这里看文章,听音乐。
没有闹市的喧哗,没有人声的嘈杂。

Wake On Lan 远程唤醒

227 views 十一月 20, 06 by Timothy

远程唤醒,是现在很多网卡都支持的功能。而远程唤醒的实现,主要是向目标主机发送特殊格式的数据包,是AMD公司制作的Magic Packedt这套软件以生成网络唤醒所需要的特殊数据包,俗称魔术包(Magic Packet)。Magic Packet格式虽然只是AMD公司开发推广的技术,并非世界公认的标准,但是仍然受到很多网卡制造商的支持,因此 许多具有网络唤醒功能的网卡都能与之兼容。
要实现远程唤醒,还需要硬件的设置:
主板和网卡必须都支持远程唤醒功能。一般目前的主板都支持这个功能,支持的主板上通常都有一个专门的3芯插座,以便在关机时为网卡供电。但
并非所有的网卡都支持该功能(特别是一些价格较便宜的低档网卡),要判断网卡是否支持远程唤醒功能的方法很简单,支持远程唤醒的网卡上都有一个3针的WOL接口和一条3芯的远程唤醒电缆,通过判断网卡是否带有WOL接口即可(有些较新的网卡可能没有WOL接口也能支持远程唤醒。这是因为现在流行的主板支持PCI2.2标准,而PCI 2.2标准不需要通过专门的WOL接口为网卡供电,允许主板直接通过PCI插槽向网卡提供Standby电源)。

1.硬件连接
网卡安装完毕后将远程唤醒电缆的一端插入到网卡的WOL接口上,另外一端与主板的3针WOL远程唤醒接口相连(该接口旁通常标有WOL_CON的字样,当然如果主板和网卡都支持PCI2.2标准则无须做这一步)。

2.CMOS设置
打开CMOS远程唤醒功能很简单,只要将CMOS设置中的“Power Management Setup”的“Wake Up On LAN”项设置为“Enable”即可。

软件的实现方面,其实就是通过socket向目标的机器发送魔术包了,魔术包的格式,包含有连续6个字节的“FF”和连续重复16次的MAC地址。程序中我们可以采用UDP方式广播发送,不需要端口号,只要知道对方机器的MAC地址即可 :)

程序运行界面如下:

程序打包下载:

点击下载此文件

C++/CLI的泛型

111 views 十一月 13, 06 by Timothy

泛型,其实在C++里面已经不是一个新概念了。他允许C++程序员参数化类型,把类型作为参数抽象出来,更好的实现代码的复用,并且使你的程序更加简洁,不用去为同一个函数重载多个不同参数类型的版本。在.NET 2.0中也加入了对泛型的支持。而随着STL也被集成到.NET中来,成为STL.NET,我们在采用C++/CLI开发的时候,就有了更多的选择。利用.NET框架所提供的数据集合System::Collection,或者是使用泛型System::Collection::Generic,还可以使用STL.NET。
Stanley B. Lippman在文章STL.NET Primer中提到,STL.NET被经过重新设计,集成到.NET中来,结合了泛型和模板的机制,看看他对STL.NET的评价:In my judgment, when combined with the
revised C++/CLI dynamic programming support, this coming version of Visual C++ is
simply the most satisfying language in which to program. I think STL.NET is a very exciting
library addition, and I hope that after you finish this series of articles you will agree with
me.
泛型与模板的应用,在C++/CLI中,会变得更有乐趣。
下面,是在C++/CLI中使用泛型、模板的一些例子。这里没有采用STL.NET,关于STL.NET的介绍,可以参考Lippman的文章:http://msdn2.microsoft.com/en-us/library/ms379600(VS.80).aspx

//这是我们自己实现的,用来模拟堆栈结构的模板类
template
ref class MyStack
{
private:
ArrayList ^ mList;
public:
MyStack()
{
mList= gcnew ArrayList();
}

void push(T const & type)
{
mList->Add(type);
}

int pop(T &value)
{
if(mList->Count > 0)
{
value=*reinterpret_cast( mList[mList->Count - 1]);
mList->RemoveAt(mList->Count – 1);
return true;
}
else
{
return false;
}
}
};

int main(array ^args)
{
//实例化这个模板类
MyStack ^ mystack = gcnew MyStack ();
mystack->push(12);
mystack->push(13);

int a,b;
mystack->pop(a);
mystack->pop(b);
Console::WriteLine("a is:{0} and b is:{1}",a,b);

//.NET 2.0提供的泛型支持,为我们封装好了一个Stack
System::Collections::Generic::Stack ^ stack =
gcnew System::Collections::Generic::Stack ();
stack->Push("World");
stack->Push("Hello");

Console::WriteLine("{0} {1}",stack->Pop(),stack->Pop());

return 0;
}

运行结果如图:

.NET中实现自绘的ListBox

180 views 十月 30, 06 by Timothy

在平常的开发过程中,我们为了改善用户的体验,通常会在界面上花一些功夫。因为清爽的界面,通常给用户带来一些耳目一新的感觉,并且能增强用户满意度。前几周的一个项目中,就用到了ListBox,需要突出用户在ListBox中选中的项,而.NET自带的ListBox由于配色过于普通,无法满足我们的需要,这就需要我们重新对ListBox的配色进行一些修改。
在Windows的消息机制中,有一个消息叫做WM_DRAWITEM,当控件(比如:Button,ComboBox,ListBox,Menu)需要被重新绘制的时候,会向该控件的父窗口发送这个消息。父窗口通过响应这个消息,就可以实现对该控件外观的绘制,也就是说,通过响应WM_DRAWITEM消息,我们可以接管系统对控件的绘制,这样,我们就可以随心所欲,用我们喜欢的方式,来绘制这个控件了。听起来不错吧?
.NET的WinForm程序,也是基于Windows的GUI界面的窗口,而.NET追溯到最底层,其实也是对Win32 API的更高一个层次的封装。所以,.NET的WinForm程序同样也逃脱不了消息机制。于是我们就可以在程序中,通过设置控件为Owner Draw属性,然后加入对WM_DRAWITEM的处理,就可以在OnDrawItem函数中,定制控件外观了。
理论上就是这样,我们开始动手吧,打造一个具有个性的ListBox控件!需要说明的是,当我们把控件属性中的DrawMode改为OwnerDrawFixed过后,.NET以及将绘制这个控件的责任交给了我们,因此我们必须要实现DrawItem函数,否则ListBox会是一片白,什么也看不到。
1.建立一个简单的工程,在工具箱拖放ListBox到Form上,然后将ListBox属性中的DrawMode改为OwnerDrawFixed,或者在Form_Load中,设置控件的属性:
this.listBox1.DrawMode = DrawMode.OwnerDrawFixed;
2.在事件窗口中,为DrawItem添加处理函数。
3.配色方案:这里,我们设定被选中的项目有一个蓝色的外框,并且选中的项中,内容呈亮绿色显示,背景色呈灰色显示,这样就更醒目一些了。
4.最后一步,就是加入OnDrawItem的代码,如下:

private void listBox1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
//定义背景色,选中为灰色,未选中为白色
Brush brNoSelectedBack=Brushes.White;
Brush brSelectedBack=Brushes.Gray;
//定义前景色,选中为亮绿色,未选中为黑色
Brush brSelectedFore=Brushes.LightGreen;
Brush brNoSelectedFore=Brushes.Black;

//定义焦点,有焦点状态下绘制蓝色外框(蓝色)
Pen penFocus=new Pen(Brushes.Blue);

e.Graphics.FillRectangle(Brushes.White,e.Bounds);

//绘制Item被选中的情况
if((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
e.Graphics.FillRectangle(brSelectedBack,e.Bounds);
//绘制焦点外框
e.Graphics.DrawRectangle(penFocus,e.Bounds.X,e.Bounds.Y,e.Bounds.Width,e.Bounds.Height-1);
e.Graphics.DrawString(this.listBox1.Items[e.Index].ToString(),
this.listBox1.Font,brSelectedFore,e.Bounds);
//e.DrawFocusRectangle();
return;
}

//绘制没有被选中的情况
e.Graphics.FillRectangle(brNoSelectedBack,e.Bounds);
e.Graphics.DrawString(this.listBox1.Items[e.Index].ToString(),
this.listBox1.Font,brNoSelectedFore,e.Bounds);
}

到这里,一个简单的自绘ListBox就实现了,不过这里的代码都是直接加载父窗体的里面,不是很美观。其实我们可以自己实现一个这样的类,并把这个ListBox编译为一个.NET控件,这样,在其他的项目中就可以很简单的重用这个控件了。:)
下面是这个自绘控件的效果,左边是我们的自绘ListBox,右边是普通的ListBox。等有时间,我会把这些封装成为一个dll控件 :)。这里提供源代码的下载,有兴趣的朋友可以再根据自己的需求进行一些自己的修改。

点击下载此文件

国庆的深圳之行

83 views 十月 10, 06 by Timothy

这次国庆去了深圳,给人的第一感觉就是热,当成都还在绵绵的秋雨当中,深圳的太阳仍旧十分火辣。回来的时候才发现以及黑了一圈。这次去深圳是因为老爸去见一个28年没有见过面的老战友,顺便带我们去深圳玩一圈。

不多说了,贴上照片 :)

首先登场的是老爸和老妈

偶和偶老婆

在深圳见到了我传说中的大学室友加哥们–首长

在海湾

偶家的Jessie

和首长–吃饭合影

海洋公园的海豚表演

海豚表演2

MVP连任成功 I'm coming back :)

150 views 十月 07, 06 by Timothy

10月6日从深圳回来,迫不及待地打开我的hotmail,果然有一封邮件在那里,标题是“恭喜你……”。很荣幸的连任MVP,被授予2007 Microsoft® MVP 称号。

在此特别感谢Microsoft,感谢Sisley,感谢CCTV。我会更加努力的。 [cool]
今天去梁振的MSN Space,看到他也连任成功,再次祝贺你哦 :)

从今日起,恢复Blog的MVP标徽。

MVP任期结束

121 views 九月 28, 06 by Timothy

不知不觉,又快一年了。而在9.30号,我的MVP一年的任期也将结束了。回顾这一年,自己又有了不少的进步。从最开始的VC到现在接触到.net,对我的发展方向也有很大的影响。MVP不仅仅是一个称号,而是一种文化、一种勉励。让我能不断的去学习新的技术,和大家一起分享。

在这一年,我有幸参加了成都的MVP Open Day,见到了传说中的MVP Leader :Sisley。也见到了Eddie Liu。认识了Eric Liu,Eric Zhong,Richie,Simon,Jack,Kim,还有Aaron Zhao,和张美波,梁振.

估计10月连任的消息会在国庆左右公布,希望自己连任能成功。从今天起,我会取消在我的blog上面的MVP徽标。希望能有机会再次将他挂上 [cool]

调试windows服务的一点经验【补充】

227 views 九月 18, 06 by Timothy

上次写过一个调试windows服务的一点经验的日志。这段时间也在做一个和Windows Service有关的东西。又有了些经验,所以拿来和大家分享下。调试windows服务,采用的一般方法,就是设好断点,然后启动服务,在IDE里面直接通过进程列表,把Service的exe附加到IDE上面来调试,这个方法在上一个日志也提到过。其实在.NET建立的服务程序中,还有一个方法,也是之前没有想到的方法,更为简单 :)

// 进程的主入口点
static void Main()
{
System.ServiceProcess.ServiceBase[] ServicesToRun;

// 同一进程中可以运行多个用户服务。若要将
//另一个服务添加到此进程,请更改下行
// 以创建另一个服务对象。例如,
//
// ServicesToRun = New System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
//
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service1() };

System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}

也就是在Main方法,服务程序开始的地方,如上,把默认的创建并运行服务的代码全部注释掉,然后直接生成本类的一个实例,然后调用OnStart方法就可以了,这里要注意的是OnStart方法是一个受保护的无返回值的方法,而Main函数是静态方法,所以需要把OnStart也改动一下,设置为静态函数。这样的话,服务和一般的.net应用程序就一样了,调试的时候更加方便,直接F5就可以了 :) 不过在完成调试过后,一定记得要把上面的改动还原 [cool]

改动后的代码如下:

// 进程的主入口点
static void Main()
{
Service1 obj=new Service1();
obj.OnStart();
}

这个方法虽然有点投机,不过确实能够节省很多步骤,让调试服务和调试一般的应用程序那样方便!值得推荐

Page: 32 of 49 1 ... 28 29 30 31 32 33 34 35 36 ... 49