Archive for the ‘东东博客’ Category

终于花了2K大洋参与基金的博弈

星期日, 3 6 月, 2007

从去年这个时候开始了解基金以来一直没敢出手去买那些需要申购手续费的开放式基金,只是陆陆续续的买了一些货币基金。考虑的主要因素是自己对这基金这方面的运作还不算了解,怕这钱投下去了就没有个回的。

货币基金申购和赎回不需要手续费,在不考虑CPI因素的情况下基本上每天都是有收入的,这样中间即使有某一天收入为负值,也不会出现把本金搭进去的情况。货币基金平均年收益是2.2%左右,与一年定期除去利息税后的收益相当,但它可以跟活期一样的灵活,能在2~3个工作日里变现。定期如果中间变现就会损失利息收益,所以货币基金是代替1~2年定期的理财品种。

在货币基金不能变现的节假日或变现中的日子里,可以合理使用信用卡应急。但不在万不得已的情况下不要使用信用卡取现,因为没有利息优惠,有的卡甚至还要扣手续费(目前已知的工行信用卡不收取现手续费)。平日里也可以将现金拿去购买货币基金,使用信用卡消费,在还信用卡时再赎回来还帐。结果当然是本月要消费的钱赚了1年定期的利息收益率,长期这样作也赚的不少的钱哟。

从开始购买货币基金以来,由于余钱不多,而且短时间内需要使用,所以始终没敢购买那些需要申购手续费的基金。5月份花掉3万把父母接到上海和北京去玩了一圈,之后短时间内急用的钱也不多了,所以经过1周的考虑后决定出手2千大洋探探路了。

前段时间从大学QQ群中了解到目前的基金“老鼠仓”太多,他们推荐购买指数基金比如嘉实300、大成300等。我5月27日在招行的银基通上了解嘉实300时看到了收益率相当的鹏华中国50,自我感觉该基金也是指数型(到现在还不知道判断对不对),而且他它们的申购是1千起,所以决定周一各购买1千试试,想看看手续费之类的是如何扣的。虽然沪指已经逛飘好长时间,相当多的人已经赚到钱,还有相当多人还在涌入,相关新闻报道股市的泡沫离暴掉的已经不远,但考虑到我这2千大洋可以放很长时间,所以就不在乎什么,亏了也亏不了多少。

5月29日收到短信,嘉实300以1.581净值成交623.16份,鹏华中国50以1.689净值成交583.32,手续费都是14.78。周二每净值分别升了3.5、3.6分,算下来已经收回成本。

周三国家开始提升印花税从1‰到3‰,结果是两市暴跌6%左右,呵呵结果当然是亏掉了。上周五的净值,嘉实300是1.48,鹏华中国50是1.592,基本上都跌1角左右。但只要我现在不赎回,再什么跌也不会有影响,过一陈子还是会升上去的,放着吧。

lower_bound在多线程下容易出问题

星期三, 30 5 月, 2007

lower_bound方法一般应用于排序的系列,比如vector、list等,在插入新的记录前通过这个方法找到插入点,当找不到插入点时追加到最后即可,由此可以生成排序的系列。同样使用这个方法可以找到系列中的某一对象,binary_search方法就是使用的这个方法。

今天我在测试一个项目时发现一个奇怪的现象,就是在多线程情况下通过这个方法查找某一对象时,系列中的某一个对象的值会发生变化,而变化的值有可能还会变成其它值,结果将会导致已排序的系列变成无序,后果可想而知。

假设系列中的每个元素是下面的结构:
typedef struct tagMbParam
{
 std::string strParamName;
 unsigned char nType;
 unsigned short nPduAddr;
} MB_PARAM, *PMB_PARAM;

我们给lower_bound指定一个排序函数,按strParamName从小到大排序:
bool MBPSortFun(MB_PARAM first, MB_PARAM second)
{
 if (first.strParamName < second.strParamName)
 {
  return true;
 }
 else
 {
  return false;
 }
}

我们用下面的方法查找某一对象:
 MB_PARAM mb;
 mb.strParamName = "要查找对象对应的值";
 系列类型::iterator it = lower_bound(系列.begin(), 系列.end(), mb, MBPSortFun);

在单线程时没有问题,在多线程情况下,系统中某一个元素中的strParamName会发生变化,导致问题出现。

我怀疑是不是lower_bound不支持多线程或支持得不够好,因此在该函数的调用前后加上临界区,问题不再出现:
 EnterCriticalSection(&s_csParam);
 系列类型::iterator it = lower_bound(系列.begin(), 系列.end(), mb, MBPSortFun);
 LeaveCriticalSection(&s_csParam);

关于网线线序

星期三, 18 4 月, 2007

RJ45跳线由标准的多股线缆和连接硬件制作而成,所有跳线均符合CAT 5E类标准。实现了通讯设备模块化,使得配线架之间的快速互连,具有极大的灵活性,并具备多种长度、颜色可供选择。并且采用50μ英寸镀金水晶头,确保产品的优异性能,渐变型受力原理的灌胶护套,防滑抗拉,保证了一定的弯曲半径。

10M双绞线接头的标准接法
线材要求CAT-3(3类线)

号码
信号定义
线对颜色
1
TX+
橙白
2
TX-
3
RX+
绿白
4
未用
5
未用
蓝白
6
RX-
绿
7
未用
棕白
8
未用

100M双绞线接头的标准接法
线材要求CAT-5(5类线),接头接法与10M完全兼容。

号码
信号定义
线对颜色
1
TX+
橙白
2
TX-
3
RX+
绿白
4
未用
5
未用
蓝白
6
RX-
绿
7
未用
棕白
8
未用

1000M双绞线接头的标准接法
线材要求CAT-5e(5类增强线,俗称超五类),接头接法与10M/100M完全兼容。

号码
信号定义
线对颜色
1
BI_DA+
橙白
2
BI_DA-
3
BI_DB+
绿白
4
BI_DC+
5
BI_DC-
蓝白
6
BI_DB-
绿
7
BI_DD+
棕白
8
BI_DD-

以上表格的线序是568B线序,对应的568A线序是“绿白 绿 橙白 蓝 蓝白 橙 棕白 棕”,对于10M/100M来说就是把TX+与RX+对调、TX-与RX-对调。

常规网线的线序两头都是568B或568A。

交叉网线(直接连接两台电脑的网线)则一头是568B另一头是568A。

新买了柯达的C743数码相机

星期四, 12 4 月, 2007

原来用的是三星S600数码相机,愚人节那天不小心从桌子上掉落摔歪了镜头。由于过了保修期,如果找维修点修的话所花的钱完全可以买一个新的了。后来自亲动手维修,镜头是修好了(维修点肯定会要求更换镜头),但安装过程中主板上一个插槽接触不好,多试几下就报废了。后来手动焊接排线来替代插槽的功能,由于排线太密不好焊,结果相机还是没法用。不过能从别人那拿到一个完好的主板还是能修好的,期待着能从网上或维修点拿到主板。

经过郑重考虑,决定再买一个1000元左右的家用相机来使用。老同事建议买佳能或尼康,花了一两天时间在网上了解这两个牌子的相机,看看别人的评价。先后对尼康的L11、L10、L3、L2,佳能的C430、C450、C540、C550感兴趣。本打算买佳能的C540,论坛中说已经停产,有人推荐柯达的C653。然后去看了一下柯达牌子的东西,了解了C653、C543、C743(相关论坛中关村在线价格查询频道)。到新蛋中国上去看有没有相关的产品买,结果发现柯达的C743有货,裸机卖价是1099,跟中关村在线价格查询频道报的价1020相差不大,本着“抵制日货”的想法,最后决定买柯达的牌子,在新蛋中国网上直接订购。昨天下的单,使用Paypal信用卡支付,今天上午就拿到货,试机感觉还可以。

STL查找时比较函数对象的实现

星期四, 29 3 月, 2007

我们在使用STL的vector或list过程中经常要用到查找操作,对于需要排序的操作则需要找到插入点。如果我们放到这些容器中的对象是我们自己定义的话则需要自己实现比较函数。

我们这里举两个例子,分别是未排序的find_if和排好序的lower_bound:

假设我们有这样一个类:
class CUser
{
public:
 CUser(const std::string& strUserName);

 std::string& GetUserName()
 {
  return m_strUserName;
 }

private:
 std::string m_strUserName;  // User name
};
typedef vector<CUser*> TUser;
typedef vector<CUser*>::iterator TUserIt;

定义一个vector类:
TUser vctUser;

1. 我们想从无序vector中找到某一个用户的对象,可以这样做:
CUser* pUser = new CUser(string("lordong"));
TUserIt itFind = find_if(vctUser.begin(), vctUser.end(), is_needed_user<CUser*>(pUser));
if (itFind != vctUser.end())
{
 // 找到
}
// 决定是否需要释放pUser的资源

is_needed_user函数对象的实现代码:
template <typename PType>
class is_needed_user : std::unary_function<PType, bool>
{
public:
 is_needed_user(const PType pArg) : m_pValue(pArg) { }
 ~is_needed_user() { }

 bool operator()(const PType p) const
 {
  return _tcsicmp(m_pValue->GetUserName().c_str(), p->GetUserName().c_str()) == 0;
 }

private:
 PType m_pValue;
};

2. 我们想从有序的vector中找到某一对象,可以这样做:
CUser* pUser = new CUser(string("lordong"));
TUserIt itFind = lower_bound(vctUser.begin(), vctUser.end(), CompareUser<CUser*>());
if (itFind != vctUser.end())
{
 // 参见binary_search函数,注意参数顺序
 if (!CompareUser<CUser*>()(pUser, *itFound))
 {
  // 找到
 }
 else
 {
  // 找到插入点
 }
}
// 决定是否需要释放pUser的资源

CompareUser函数对象的实现代码:
template<typename Ty>
struct CompareUser : public std::binary_function<Ty, Ty, bool>
{
 bool operator()(const Ty& first, const Ty& second)
 {
  return _tcsicmp(first->GetUserName().c_str(), second->GetUserName().c_str()) < 0;
 }
};

 

使用COM组件创建快捷方式的实现

星期一, 26 3 月, 2007

从网上搜罗得到一个创建快捷方式的解决方案,对其进行整理并写成可独立使用的函数:

// Create shortcut
// @param lpszSource LPCTSTR Source file name or file path
// @param lpszShortcut LPCTSTR Shortcut name, e.g. Notepad.lnk
BOOL CreateShortcut(LPCTSTR lpszSource, LPCTSTR lpszShortcut)
{
 HRESULT hr;
 IShellLink* psl = NULL;
 IPersistFile* ppf = NULL;
 WORD wsz[MAX_PATH];
 BOOL bInitCom = FALSE;
 BOOL bRet = FALSE;

 do {
  hr = CoCreateInstance(CLSID_ShellLink, NULL ,CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
  if (!bInitCom && FAILED(hr))
  {
   bInitCom = TRUE;
   hr = CoInitialize(NULL);
  }
  else
  {
   break;
  }
 } while(SUCCEEDED(hr));
 
 if(SUCCEEDED(hr))
 {
  psl->SetPath(lpszSource);
  hr = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
  if(SUCCEEDED(hr))
  {
   MultiByteToWideChar(CP_ACP, 0, lpszShortcut, -1, wsz, MAX_PATH);
   bRet = SUCCEEDED(ppf->Save(wsz, STGM_READWRITE));

   ppf->Release();
  }
  psl->Release();
 }
 
 if (bInitCom)
 {
  CoUninitialize();
 }

 return bRet;
}

宝贝计划视频推荐

星期一, 19 3 月, 2007

今晚9时在切换电视频道时被CETV-1台的《亲亲宝贝》之《思想之光》所吸引,被片中那种任由孩子自由发挥的方法所感触,该法很值得学习。

宝贝能在一大堆玩具中摸索,逐步了解各个玩具的用处。

宝贝能通过不断的按播放机上的按钮根据机器的反应熟悉播放机的使用。

宝贝能自己思考通过各种途径拿到自己想到的东西。

……

个人感觉该片对宝贝的启发教育很有帮助,在此记录下来,准备在空余的时候去找找,BT下载或购买都行。

今天是妇女节,祝老婆大人节日快乐!

星期四, 8 3 月, 2007
妇女节从啥时候开始,咱不得而知,不过知道这天是大老爷们最头疼的事,得花钱吧,家务得自己干吧,哎真希望也有个妇男节,让咱大老爷们争口气呀。
听听咱家那口子啥说的:
歪歪袁: 大家都跟我说节日快乐,你怎么不祝我节日快乐啊
呵呵
LorDong: 谁说了来着
歪歪袁: 李小强都跟我说了的
呵呵
LorDong: 你是“妇女”吗,嘎嘎
歪歪袁: 还有很多同学啊,群啊,都说了,邻居啊
LorDong: 你老公怎么能跟别人一样呢
歪歪袁: 呵呵
那你要怎么个语众不同啊
LorDong: 不说呀
歪歪袁: 切
呵呵,该吃饭了,希望下午我们放假
LorDong: 嗯好
歪歪袁: 咔咔,我有新手机了,中午回去拿
看,要不是昨天给她买了个新手机,今天可就惨了……

用SetForegroundWindow将窗体提到最前的实现

星期四, 8 3 月, 2007

前段时间写的C#程序启动欢迎窗体实现,在运行时虽然能显示欢迎窗体,但运行后不能把主窗体提到最前。结合网上搜罗了好多资料,自己做了好几个方案来实现,最终可以解决了。

起因:
2000/XP 改变了SetForegroundWindow的执行方式,不允许随便把窗口提前,打扰用户的工作。

思路:
可以用附加本线程到最前面窗口的线程,从而欺骗windows。

实现:
原理:将显示欢迎窗体的线程作为Foreground的线程。
1. API函数的导入
public const int SW_HIDE = 0;
public const int SW_NORMAL = 1;
public const int SW_SHOWMINIMIZED = 2;
public const int SW_SHOWMAXIMIZED = 3;

[DllImport(“User32.dll”)]
public static extern void SetForegroundWindow(IntPtr hwnd);

[DllImport(“User32.dll”)]
public static extern IntPtr GetForegroundWindow();

[DllImport(“User32.dll”)]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, IntPtr pProcId);

[DllImport(“User32.dll”)]
public static extern bool AttachThreadInput(int idAttach, int idAttachTo, int fAttach);

[DllImport(“User32.dll”)]
public static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);

2. 使用API函数实现
private static void ActivateMainInstance(IntPtr mainWindowHandle, int foreId)
{
int curId = GetWindowThreadProcessId(mainWindowHandle, IntPtr.Zero);

if (curId != foreId)
{
AttachThreadInput(foreId, curId, 1);
SetForegroundWindow(mainWindowHandle);
AttachThreadInput(foreId, curId, 0);
}
else
{
SetForegroundWindow(mainWindowHandle);
}
ShowWindowAsync(mainWindowHandle, SW_SHOWMAXIMIZED);
}

3. 调用:
private static ApplicationContext _context = null;
private static SplashScreen _splash = null;
private static MainFrame _mForm = null;

private static void OnAppIdle(object sender, EventArgs e)
{
if (_context.MainForm == null)
{
Application.Idle -= new EventHandler(OnAppIdle);

// Initialize main frame and show
_mForm.InitializeFrame(); // 花时间点
_context.MainForm = _mForm;
_context.MainForm.Show();

// Active main form
ActivateMainInstance(_mForm.Handle, _splash.ThreadId);

// Close splash screen
_splash.Close();
_splash = null;
}
}

4. Main函数中:
// Show splash screen
_splash = new SplashScreen();
_splash.Run();

// Application running
_mForm = new MainFrame();
_context = new ApplicationContext();
Application.Idle += new EventHandler(OnAppIdle);
Application.Run(_context);

5. SplashScreen的实现:
public class SplashScreen
{
private SplashForm _sForm = null;
private Thread _workThread = null;

///

/// Thread function: shows this splash form.
///

private void Show()
{
_sForm = new SplashForm();
_sForm.ShowDialog();
}

///

/// Thread id property
///

public int ThreadId
{
get
{
return _workThread.ManagedThreadId;
}
}

///

/// Runs this instance.
///

public void Run()
{
_workThread = new Thread(new ThreadStart(Show));
_workThread.Start();
}

///

/// Closes this instance.
///

public void Close()
{
if (_sForm != null)
{
_sForm.HideSplash = true;
_workThread.Join();
_workThread = null;
}
}
}

C#PropertyGrid多行编辑实现

星期四, 1 3 月, 2007

如要在PropertyGrid中显示多行编辑时需要重载UITypeEditor类并修改EditorAttribute属性。

1. 重载类MultilineTextEditor
public class MultilineTextEditor : UITypeEditor
{
private static ILog _log = LogManager.GetLogger(typeof(MultilineTextEditor));

public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}

public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
try
{
IWindowsFormsEditorService svc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

if (svc != null)
{
if (value is string)
{
TextBox box = new TextBox();

box.AcceptsReturn = true;
box.Multiline = true;
box.Height = 120;
box.BorderStyle = BorderStyle.None;
box.Text = value as string;
svc.DropDownControl(box);

return box.Text;
}
}
}
catch (Exception ex)
{
if (_log.IsErrorEnabled)
{
_log.Error(“MultilineTextEditor error: ” + ex.Message);
}

return value;
}

return value;
}
}

2. 增加EditorAttribute属性
[DescriptionAttribute(“The item description.”),
EditorAttribute(typeof(MultilineTextEditor), typeof(System.Drawing.Design.UITypeEditor))]
public string Description
{
get { return _data.Description; }
set { _data.Description = value; }
}

3. 将包含各个属性的类实例赋给PropertyGrid的SelectedObject属性,即可通过这个实现进行读写操作。

4. PropertyGrid 的部分外观特征
通过 HelpBackColor、HelpForeColor 和 HelpVisible 属性可以更改背景颜色、更改字体颜色或隐藏说明窗格。
通过 ToolbarVisible 属性可以隐藏工具栏,通过 BackColor 属性可以更改工具栏的颜色,通过 LargeButtons 属性可以显示大工具栏按钮。
使用 PropertySort 属性可以按字母顺序对属性进行排序和分类。
通过 BackColor 属性可以更改拆分器的颜色。
通过 LineColor 属性可以更改网格线和边框。

5. 部分属性的显示方式
DescriptionAttribute – 设置显示在属性下方说明帮助窗格中的属性文本。这是一种为活动属性(即具有焦点的属性)提供帮助文本的有效方法。
CategoryAttribute – 设置属性在网格中所属的类别。当您需要将属性按类别名称分组时,此特性非常有用。如果没有为属性指定类别,该属性将被分配给杂项类别。可以将此特性应用于所有属性。
BrowsableAttribute – 表示是否在网格中显示属性。此特性可用于在网格中隐藏属性。默认情况下,公共属性始终显示在网格中。
ReadOnlyAttribute – 表示属性是否为只读。此特性可用于禁止在网格中编辑属性。默认情况下,带有 get 和 set 访问函数的公共属性在网格中是可以编辑的。
DefaultValueAttribute – 表示属性的默认值。如果希望为属性提供默认值,然后确定该属性值是否与默认值相同,则可使用此特性。
DefaultPropertyAttribute – 表示类的默认属性。在网格中选择某个类时,将首先突出显示该类的默认属性。