Archive for the ‘东东博客’ Category

自己写的黑莓手机IPD编辑工具BBerIPD

星期日, 31 8 月, 2008

黑莓手机的“桌面管理器”能把手机里的信息备份成IPD文件,也能导入IPD文件,这很方便。但在bbs.maxpda.com论坛里没有找到合适的IPD查看、编辑工具。

对我来说,能通过电脑来管理手机的“记事本”、“地址簿”,能导出手机里的“短信”内容是我最想要的,论坛里的IPDManager没办法打开仅包含这些内容的IPD文件,IPDEditor又依赖于.NET Framework 2.0,而我的电脑安装有这个Framework仍不能使用,所以我抽空研究了一下这几类信息的格式,自己写了一个BBerIPD工具,主要功能是:查看和编辑“记事本”、“地址簿”,查看“短信”内容,将选择的内容复制出来。

注意:修改后需要使用“导出IPD”功能才会生效!

(更多…)

发现了一个CListCtrl::GetItemText的Bug及解决方案

星期日, 31 8 月, 2008

近段在写个小程序时发现了CListCtrl::GetItemText的Bug,微软的源代码如下:

VC6对应文件: VC98\MFC\SRC\winctrl2.cpp
VC7.1对应文件: Vc7\atlmfc\src\mfc\winctrl2.cpp
CString CListCtrl::GetItemText(int nItem, int nSubItem) const
{
 ASSERT(::IsWindow(m_hWnd));
 LVITEM lvi;
 memset(&lvi, 0, sizeof(LVITEM));
 lvi.iSubItem = nSubItem;
 CString str;
 int nLen = 128;
 int nRes;
 do
 {
  nLen *= 2;
  lvi.cchTextMax = nLen;
  lvi.pszText = str.GetBufferSetLength(nLen);
  nRes  = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem,
   (LPARAM)&lvi);
 } while (nRes == nLen-1);
 str.ReleaseBuffer();
 return str;
}

问题出在标红色的句子,我发现如果读取的第(lvi.pszText + lvi.cchTextMax – 1)字节刚好是双字节字符的第一个字节时(比如中文汉字的第一个字节),该字节最后被替换为’\0’(这符合lvi.pszText以’\0’结尾的约定),但返回读取的字节数是lvi.cchTextMax而不是预想的(lvi.cchTextMax-1),导致(nRet == nLen-1)结果为FALSE而结束读取数据,但是数据仍没有读完,需要继续读取。

解决办法很简单,把(nRet == nLen-1)改成(nRet >= nLen – 1),真搞不懂为什么没有人向微软反应这个错误并促使他们改过来呢。

我自己写了一个外部函数:

CString GetItemText(CListCtrl& lvw, int nItem, int nSubItem)
{
 ASSERT(::IsWindow(lvw.m_hWnd));
 LVITEM lvi;
 memset(&lvi, 0, sizeof(LVITEM));
 lvi.iSubItem = nSubItem;
 CString str;
 int nLen = 128;
 int nRes;
 do
 {
  nLen *= 2;
  lvi.cchTextMax = nLen;
  lvi.pszText = str.GetBufferSetLength(nLen);
  nRes  = (int)::SendMessage(lvw.m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem,
   (LPARAM)&lvi);
 } while (nRes >= nLen-1);
 str.ReleaseBuffer();
 return str;
}

Oracle怎样修改查看字符集及字符集?

星期二, 26 8 月, 2008

[Q]怎么样查看数据库字符集
[A]
数据库服务器字符集select * from nls_database_parameters,其来源于props$,是表示数据库的字符集。
客户端字符集环境select * from nls_instance_parameters,其来源于v$parameter,表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表
会话字符集环境 select * from nls_session_parameters,其来源于v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是alter session完成,如果会话没有特殊的设置,将与nls_instance_parameters一致。
客户端的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符。如果多个设置存在的时候,alter session>环境变量>注册表>参数文件字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符集是zhs6gbk,则nls_lang可以是American_America.zhs6gbk。

[Q]怎么样修改字符集
[A]8i以上版本可以通过alter database来修改字符集,但也只限于子集到超集,不建议修改props$表,将可能导致严重错误。
Startup nomount;
Alter database mount exclusive;
Alter system enable restricted session;
Alter system set job_queue_process=0;
Alter database open;
Alter database character set zhs6gbk;

今天是个特殊的日子:老爸33周岁生日儿子刚好是第99天

星期六, 23 8 月, 2008

今天是老爸农历33周岁生日,恰逢儿子第99天,成立的公式是:儿子=老爸×3,看来儿子将来要比老爸有出息呀。

早上外面下着小雨,一家三口睡到9点才起床,10点半才吃早饭。由于下雨懒得出去买菜就决定中午出去吃面,12点过宝宝想睡觉于是我哄着他一起睡觉,一睡就到了下午2点半,起来推着童车带宝宝去外面的“唐韵秦风”吃手擀面,算是吃了长寿面吧。

3点过吃完午饭后一路推着童车沿着福山路、张杨路到第一八佰伴,宝宝一路上在睡觉直到到了第一八佰伴的8楼把他抱起来他才醒。第一次带宝宝逛街,小家伙兴奋得很,笑呵呵的到处看。

下午5点半沿着浦东南路、世纪大道、乳山路回来,老婆还在乳山路近东方路的克里丝汀买了一个抹茶的小蛋糕回来,说是为我庆祝生日,其实那个蛋糕卷是我公司送给我的,呵呵。

刚才找了一年前买的大蜡烛出来点,算是生日蜡烛吧,许完愿使劲把蛋糕吃完,同时也消除了老婆因男子10米跳台没能拿到第50枚金牌而懊恼的情绪。

老爸已经上了而立之年了,接下来的事情应该是多多挣钱让宝宝过得好一些,但愿宝宝能健康快乐的成长!

五笔输入法字根助记词

星期五, 8 8 月, 2008
11G 王旁青头戋五一
12F 土士二干十寸雨
13D 大犬三(羊)古石厂 (“羊”指羊字底)
14S 木丁西
15A 工戈草头右框七 (“右框”即“匚”)
21H 目具上止卜虎皮 (“具”指具字的上部)
22J 日早两竖与虫依
23K 口与川,字根稀
24L 田甲方框四车力 (“方框”即“囗”)
25M 山由贝,下框几
31T 禾竹一撇双人立,反文条头共三一 (“条头”即“夂”)
32R 白手看头三二斤
33E 月彡(衫)乃用家衣底
34W 人和八,三四里
35Q 金勺缺点无尾鱼,犬旁留儿一点夕,氏无七(妻)
41Y 言文方广在四一,高头一捺谁人去
42U 立辛两点六门病(疒)
43I 水旁兴头小倒立
44O 火业头,四点米
45P 之宝盖,摘礻(示)衤(衣)
51N 已半巳满不出己,左框折尸心和羽
52B 子耳了也框向上
53V 女刀九臼山朝西(彐)
54C 又巴马,丢矢矣(厶)
55X 慈母无心弓和匕,幼无力(幺)

自己写的音乐播放列表生成工具PlaylistMaker

星期四, 31 7 月, 2008

从bbs.maxpda.com论坛下到两个播放器:multiPlay和KD_Player_8800_8300,与黑莓自带的音乐播放器比较有好处也有缺点,下面粗略的作了一下比较:

multiPlay
优点:可以创建播放列表,能整个目录添加文件;在待机模式可以播放。
缺点:不支持wma等格式;播放列表不能改名,也不支持中文,只能有一个播放列表;打不开m3u播放列表。

KD_Player_8800_8300
优点:可以创建播放列表,列表名可以支持中文也可以改名,能整个目录添加文件;在待机模式可以播放;支持wma等格式。
缺点:播放列表不能保存;打不开m3u播放列表。

黑莓自带音乐播放器
优点:可以创建播放列表,列表可以保存,支持中文,可以打开m3u播放列表;支持wma等格式。
缺点:在待机模式不能播放;播放列表不能整个目录添加文件,添加文件很麻烦。

(更多…)

自已写的COD文件加载工具CodLoader

星期三, 23 7 月, 2008

bbs.maxpda.com论坛上下载到网友写的WinLoader.exe来给自己的BlackBerry加/卸载COD文件,总感觉有些不方便的地方,因此自己花了点时间也写了一个只针对COD的加/卸载工具CodLoader.exe,与论坛上下载到JavaLoader.exe配合使用可以比较方便的管理COD文件。

运行界面:

(更多…)

VC中SetIcon的应用

星期三, 23 7 月, 2008

VC的MFC向导生成的窗体自动包含以下两句:
 SetIcon(m_hIcon, TRUE);   // Set big icon
 SetIcon(m_hIcon, FALSE);  // Set small icon
用于设置主框架的图标,第一句是使用大图标作主框架的图标,第二名是使用小图标作主框架的图标,一般情况下主框架的图标总是小图标,所以可以把第一句注释掉。

至于如何设置在资源管理器中看到的图标呢,解决办法是把要在资源管理器显示的图标的ID值改为最小,打开resource.h文件就可以看到“#define 宏变量 ID值”,自行调整ID值即可。

这两个图标可以设成不一样的,那么在资源管理器里和程序的主框架就可以看到不同的图标了。

电驴客户端eMule只有LowID且端口是2128的解决办法

星期五, 11 7 月, 2008

使用www.verycd.com上的电驴客户端eMule,已经在路由器配置好端口映射且已经在防火墙上开了端口,仍然是LowID,日志里显示的TCP和UDP的端口都是2128,解决方法如下:

1. 右击状态栏,选择“定制工具条”,把“Kad”和“服务器”添加到“当前工具条按钮”中,目的是可以重新选择服务器,默认情况下这新按钮都不显示,如下图:

2. 打开“选项”窗体,选中“扩展设置”,把“在UPnP中,尝试使用随机端口”前的钩去掉,此法可以禁止2128端口的出现,如下图:

3. 点击工具条上的“服务器”按钮,按“优先级”排列,在优先级是“高”的项里选择一个“Ping”值比较小的项右击选择“连接到所选的服务器”,看看有没有获得HighID,如果没有再试试连别的服务器,如下图:

当然要获取HighID,必须确保从外网能够连接到本地的指定TCP端口,可以在“选项”窗体的“连接”组里点“测试端口”,如果显示“TCP测试成功”,说明可以获取HighID,如下图:

总结:在符合获取HighID的情况下,选择不同的服务器可能会获取LowID,此时应不允许UPnP使用随机端口并选择不同的服务器来试试。

VC中Picture Control透明背景实现

星期四, 26 6 月, 2008

在VC中使用Picture Control来放置图片时想做成透明背景的,选择Bitmap类型时是图片原样显示出来的,想做成透明的Icon然后在Picture Control中选择Icon类型,可是控件缩成了一个图标。最后只能选择Bitmap类型,因为用这种模式可以把很多图片使用多个Picture Control组合起来。

在网上找了一些资料,经过自己多方的实验,终于可以搞定。

原理是重载Picture Control,在窗体初始化时给控件设置图片ID,并去掉控件的Bitmap类型,即设置成“无”类型,然后在OnPaint方法中重画图片。

处理步骤是:
1. Picture Control仍使用Bitmap类型,选择正确的图片并布局好。
2. 在窗体初始化时给控件设置具体的图片ID。

重载的类源码.h文件:
#pragma once

class CTransparentPic : public CStatic
{
 DECLARE_DYNAMIC(CTransparentPic)

public:
 CTransparentPic();
 virtual ~CTransparentPic();

 void SetBitmapIndex(UINT nBitmapIndex);

protected:
 DECLARE_MESSAGE_MAP()

public:
 afx_msg BOOL OnEraseBkgnd(CDC* pDC);
 afx_msg void OnPaint();

private:
 UINT m_nBitmapIndex; // Bitmap index of resource
};

.cpp文件:
#include "stdafx.h"
#include "TransparentPic.h"

IMPLEMENT_DYNAMIC(CTransparentPic, CStatic)

CTransparentPic::CTransparentPic()
 : m_nBitmapIndex(0)
{
}

CTransparentPic::~CTransparentPic()
{
}

BEGIN_MESSAGE_MAP(CTransparentPic, CStatic)
 ON_WM_ERASEBKGND()
 ON_WM_PAINT()
END_MESSAGE_MAP()

void CTransparentPic::SetBitmapIndex(UINT nBitmapIndex)
{
 ModifyStyle(SS_BITMAP, 0);  // Remove bitmap style, use owner paint

 bool bForceRedraw = (m_nBitmapIndex != nBitmapIndex);

 m_nBitmapIndex = nBitmapIndex;

 // Force owner paint
 if (::IsWindow(m_hWnd) && bForceRedraw)
 {
  Invalidate();
 }
}

// CTransparentPic message handlers
BOOL CTransparentPic::OnEraseBkgnd(CDC* pDC)
{
 return TRUE;
}

void CTransparentPic::OnPaint()
{
 CWnd::Default(); // Calls the default window procedure

 CClientDC dc(this);
 CBitmap bmp;

 // Try to load bitmap
 if (bmp.LoadBitmap(m_nBitmapIndex))
 {
  CDC memDC;

  memDC.CreateCompatibleDC(NULL);

  CBitmap* pOldBmp = memDC.SelectObject(&bmp);
  BITMAP bitmap;

  bmp.GetBitmap(&bitmap);
  TransparentBlt(dc.m_hDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight,
   memDC.m_hDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, RGB(236, 233, 216));

  memDC.SelectObject(pOldBmp);
  memDC.DeleteDC();
 }
 else
 {
  // Draw error information
  dc.TextOut(1, 1, _T("ERROR!"));
 }
}
说明一下:上面的RGB(236, 233, 216)指的是制作图片时以该颜色值作为背景色(要改一起改),TransparentBit方法在处理时自动把这些颜色值过滤掉,看起来就是透明的。

然后给Picture Control指定一个ID,在对话框的.h文件中定义CTransparentPic对象:
 CTransparentPic m_ctrlPic1;

接着在对话框.cpp文件的DoDataExchange方法CDialog::DoDataExchange之后加一项完成关联:
 CDialog::DoDataExchange(pDX);
 DDX_Control(pDX, IDC_BITMAP1, m_ctrlPic1);

最后在对话框的OnInitDialog加一项设置图片ID项:
 m_ctrlPic1.SetBitmapIndex(IDB_BITMAP1);