服不服?

不服就证明给自己看

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  6 随笔 :: 8 文章 :: 6 评论 :: 0 Trackbacks

2007年12月12日 #

        两天前我解答 [shutle] 网友计算闰年方法的时候,回答错误,在这里一并更正并致歉。后来查阅了资料,现把计算方法和原理粘贴一下:

        我们知道地球自转一圈为1天,地球围绕太阳公转一圈为1年。那1年到底等于多少天哪?答案是:1年=365天5小时48分46秒,即 365.242199[074] 天(注:用[xxx]表示无限循环)

因此,4年 = 4*365.242199[074] = 4*365 + 0.9687[962] 天
显然,每隔4年,就要多出了将近1天,因此公元历法就定义㈠:每4年加一天,即闰年(366天)
那么,也就是说4年就多算了:1-0.9687[962] = 0.0312[037]天

        照这样算下去,100年中有25次闰年,那么就会多计算了 25*0.0312[037]=0.7800[925] 天,这又太接近1天了,因此公元历法就定义㈡:每100年的那年不算闰年
于是:
    100年中就又会少算 1-0.7800[925]=0.2199[074] 天
    200年会少算 2*0.2199[074] = 0.439[814] 天
    300年会少算 3*0.2199[074] = 0.6597[2] 天
    400年会少算 4*0.2199[074] = 0.87[962] 天

停!400年后的误差又接近1天了,于是公元历法进行修正㈢:400年的那年(虽然是100年的倍数),但又算闰年啦。于是,400年的时候,由于多算了一次闰年,那么,
每隔400年就会多算:1-0.87[962] = 0.12[037] 天

        显然,等到4000年的时候(那时,看到这个帖子的人都死了2000年了),误差又到1天多了,也许那个时候公元历法有会进行修改了“每4000年少一个闰年”。哈哈,反正不管我们的事了。但也不尽然,因为地球的自转很不稳定,但总的趋势是每年要慢一丁点(大家是否还记得今年2006年元旦,全世界的人都要把表拨慢1秒钟?)由于阴差阳错,也许4000年后并不需要少算一个闰年也不一定呐。总结一下闰年的算法:
㈠ 每4年一闰        ㈡ 每100年的那年不闰        ㈢ 每400年的那年又闰
真罗嗦,用咱们IT人的话说,就是能被4整除但不能被100整除,可是却能被400整除的年是闰年

posted @ 2007-12-12 13:37 我的梦想我的游戏 阅读(438) | 评论 (0)编辑 收藏

2007年12月11日 #

困扰了一周的cp命令问题总算解决了,

现象:CP命令拷贝文件,新生成的文件为只读属性

原因:文件所在的盘文件格式为NTFS,不知道由于什么深层原因会导致如此

解决:重新格式化为FAT32,就OK了

在这里mark一下
posted @ 2007-12-11 16:40 我的梦想我的游戏 阅读(120) | 评论 (1)编辑 收藏

好久没看书了,
准备把这个好好看一下,
希望不要令我失望

《TCP-IP详解》

posted @ 2007-12-11 16:36 我的梦想我的游戏 阅读(80) | 评论 (0)编辑 收藏

2006年4月25日 #

http://www.cppblog.com/Files/waterczh/d3d9_example.rar
posted @ 2006-04-25 11:20 我的梦想我的游戏 阅读(100) | 评论 (0)编辑 收藏

2006年4月24日 #

QQ API设计说明书
深圳腾讯计算机系统有限公司

目录
一、引言
1.1 编写目的
1.2 更新时间
二、总体设计
三、注册的系统消息
3.1 WM_QQAPI_REGISTER
3.2 WM_QQAPI_REGISTER_RESP
3.3 WM_QQAPI_AVAILABLE
四、从设备到QQ的自定义事件
4.1 EVENT_QQAPI_SET_AUDIODEVICE
4.2 EVENT_QQAPI_GET_USERINFO
4.3 EVENT_QQAPI_PRESS_KEY
4.4 EVENT_QQAPI_CALL
4.5 EVENT_QQAPI_MUTE
4.6 EVENT_QQAPI_UNREGISTER
五、从QQ到设备的自定义事件
5.1 EVENT_QQAPI_USERINFO
5.2 EVENT_QQAPI_STATUS_CHANGE
5.3 EVENT_QQAPI_SHUTDOWN
六、双向的自定义事件
6.1 EVENT_QQAPI_CALL_STATUS
七、错误码定义
7.1 从QQ到设备――EVENT_QQAPI_ERROR
八、参数类型码表


一、引言

1.1 编写目的

本文档提供了QQ API接口说明,以供第三方应用程序使用,用于QQ和硬件设备(例如USB Phone)的交互。

1.2 更新时间

最后修订日期:2005-05-24
版本号:v1.0

二、总体设计

QQ应用程序和第三方应用程序以收发消息的方式进行通讯。
双方未成功注册之前,采用RegisterWindowMessage(Windows API)注册的系统消息进行交互,注册成功后,双方分别获取对方的窗口句柄,接下来的交互通过收发WM_COPYDATA(Windows消息)消息完成。
WM_COPYDATA的wParam参数为发送方的窗口句柄,lParam为指向COPYDATASTRUCT结构的指针,COPYDATASTRUCT定义如下:

						typedef struct tagCOPYDATASTRUCT{			
			
						?????? ULONG_PTR????????????? dwData; 			
			
						???????DWORD???? ??????????? cbData; 			
			
						???????PVOID???? ????????????? lpData; 			
			
						}COPYDATASTRUCT, *PCOPYDATASTRUCT;			
			
						dwData:事件码,标示传送的消息事件码 			
			
						lpData:消息参数,采用多个相连的“类型(1字节)+长度(4字节)+值”的格式。所有的参数类型码表见8 参数类型码表 			
			
						cbData:消息参数总长度,单位字节 			
			

三、注册的系统消息

第三方程序使用Windows SDK――RegisterWindowMessage,进行下列系统消息的注册。例如:RegisterWindowMessage(“WM_QQAPI_REGISTER”);

3.1 WM_QQAPI_REGISTER

消息名:注册消息
方向:设备àQQ
wParam:发送方的窗口句柄
lParam:QQ API版本号,目前为100,表示1.00。
第三方应用程序启动并检测到可用的设备后,向所有Windows窗口广播这个消息,带上自己的窗口句柄作为消息参数,如下:
SendMessage( HWND_BROADCAST, WM_QQAPI_REGISTER, 发送端窗口句柄, 0);
当QQ收到这个消息时,弹出“外设控制”窗口等待用户选择,如下:
QQ

3.2 WM_QQAPI_REGISTER_RESP

消息名:注册回复消息
方向:QQà设备
wParam:值如下:
WAITING(1):等待用户选择
OK(2):用户选择“允许使用”
REJECT(3):用户选择“禁止使用”
lParam:当wParam为OK(2)时,lParam为QQ应用程序的窗口句柄。
当用户选择“禁止使用”之后,如果第三方应用程序再次发送WM_QQAPI_REGISTER消息,QQ不再弹出“QQ安全警告”框,直接返回REJECT的WM_QQAPI_REGISTER_RESP消息,直到QQ程序重新启动为止。

3.3 WM_QQAPI_AVAILABLE

消息名:QQ API可用消息
方向:QQà设备
wParam:发送方的窗口句柄,即QQ程序的窗口句柄
lParam:QQ API版本号,目前为1
当QQ启动后,向所有Windows窗口广播这个消息:
SendMessage( HWND_BROADCAST, WM_QQAPI_AVAILABLE, QQ窗口句柄, 0);
当第三方应用程序收到这个消息时,再发起WM_QQAPI_REGISTER消息进行注册。这种情况出现在,当第三方应用程序先启动,而QQ程序后启动的情况下。

四、从设备到QQ的自定义事件

4.1 EVENT_QQAPI_SET_AUDIODEVICE

事件说明:设置QQ使用的音频设备
参数说明:WM_COPYDATA中的参数COPYDATASTRUCT结构说明详见2
dwData(事件码):10
lpData:如下表
cbData:消息参数总长度


参数类型码

长度

值说明

5

设备名长度

音频设备名,类型:以Null结尾的字符串

6

4字节

音频设备的设备ID号,类型:DWORD

第三方应用程序可通过音频设备名字字符串或者通过设备ID号,来发送设置音频设备事件。

4.2 EVENT_QQAPI_GET_USERINFO

事件说明:获取QQ用户信息
参数说明:WM_COPYDATA中的参数COPYDATASTRUCT结构说明详见2
dwData(事件码):11
lpData:NULL
cbData:0
QQ返回的用户信息,见5.1 EVENT_QQAPI_USERINFO。

4.3 EVENT_QQAPI_PRESS_KEY

事件说明:发送按键消息,当用户在设备上按下任何键时,发送此事件给QQ
参数说明:WM_COPYDATA中的参数COPYDATASTRUCT结构说明详见2
dwData(事件码):12
lpData:如下表
cbData:消息参数总长度


参数类型码

长度

值说明

7

1字节

键值,详见“键值映射表”

键值映射表:


键名

键值

0

0x80

1

0x81

2

0x82

3

0x83

4

0x84

5

0x85

6

0x86

7

0x87

8

0x88

9

0x89

Down

0x8D

Up

0x8E

Clear

0x8F

OK (呼叫键)

0x91

Cancel (挂断键)

0x92

STAR (*)

0x93

SHARP (#)

0x94

Mute (静音键)

0x95

RINGTONG (切换铃声键)

0x96

4.4 EVENT_QQAPI_CALL

事件说明:直接呼叫一个好友用户
参数说明:WM_COPYDATA中的参数COPYDATASTRUCT结构说明详见2
dwData(事件码):13
lpData:如下表
cbData:消息参数总长度
通过QQ号呼叫:


参数类型码

长度

值说明

1

QQ号长度

QQ号,类型:以Null结尾的字符串

通过昵称呼叫:


参数类型码

长度

值说明

2

昵称长度

昵称,类型:以Null结尾的字符串

通过速播号呼叫:


参数类型码

长度

值说明

3

速播号长度

速播号,类型:以Null结尾的字符串

通过PSTN号码呼叫:


参数类型码

长度

值说明

4

PSTN号码长度

PSTN号码,类型:以Null结尾的字符串

4.5 EVENT_QQAPI_MUTE

事件说明:静音设置,根据参数决定是打开静音或者关闭静音
参数说明:WM_COPYDATA中的参数COPYDATASTRUCT结构说明详见2
dwData(事件码):14
lpData:如下表
cbData:消息参数总长度


参数类型码

长度

值说明

12

1字节

静音状态标志。1:静音打开;0:静音关闭

4.6 EVENT_QQAPI_UNREGISTER

事件说明:反注册
参数说明:WM_COPYDATA中的参数COPYDATASTRUCT结构说明详见2
dwData(事件码):15
lpData:NULL
cbData:0
当第三方应用程序退出时,向QQ发送此事件消息,QQ将音频设备切换回系统原有设备。

五、从QQ到设备的自定义事件

5.1 EVENT_QQAPI_USERINFO

事件说明:返回本地QQ用户信息。对应于4.2 EVENT_QQAPI_GET_USERINFO
参数说明:WM_COPYDATA中的参数COPYDATASTRUCT结构说明详见2
dwData(事件码):16
lpData:如下表
cbData:消息参数总长度


参数类型码

长度

值说明

1

QQ号长度

QQ号,类型:以Null结尾的字符串

2

昵称长度

昵称,类型:以Null结尾的字符串

5.2 EVENT_QQAPI_STATUS_CHANGE

事件说明:QQ上的各种状态变化通知
参数说明:WM_COPYDATA中的参数COPYDATASTRUCT结构说明详见2
dwData(事件码):17
lpData:如下表
cbData:消息参数总长度
状态变化类型说明:

  1. DIALNUM

说明:拨号时的号码变化。参数子项依次为:


参数类型码

长度

值说明

11

1字节

DIALNUM,状态变换类型码:1

1

QQ号长度

QQ号,类型:以Null结尾的字符串

当用户拨号,QQ在收号时,如果号码发生变换,例如用户在键盘上按一个号码,或用户在PC上按一个号码,或用户按清除键Clear,那么,QQ向第三方程序发送此事件通知。第三方程序可通过此事件通知来进行拨号过程中LCD的显示操作。

5.3 EVENT_QQAPI_SHUTDOWN

事件说明:关闭QQ应用程序
参数说明:WM_COPYDATA中的参数COPYDATASTRUCT结构说明详见2
dwData(事件码):18
lpData:NULL
cbData:0
当QQ应用程序退出时,向第三方程序发送此事件消息。

六、双向的自定义事件

6.1 EVENT_QQAPI_CALL_STATUS

事件说明:呼叫状态通知
参数说明:WM_COPYDATA中的参数COPYDATASTRUCT结构说明详见2
dwData(事件码):19
lpData:如下表
cbData:消息参数总长度
呼叫状态类型说明:
(1)CONNECTING
方向:从QQ到设备
说明:呼出,正在等待对方应答。参数子项依次为:


参数类型码

长度

值说明

8

1字节

CONNECTING,呼叫状态类型码:1

9

4字节

呼叫句柄(CallHandle),类型:DWORD

10

1字节

通话人数,类型:char

1

QQ号长度

QQ号,类型:以Null结尾的字符串

2

昵称长度

昵称,类型:以Null结尾的字符串

其中,呼叫句柄为QQ分配的唯一呼叫标识符;通话人数为同时呼出的QQ个数;接下来紧跟的2个参数子项为被呼叫的QQ好友信息,如果被呼叫的QQ好友有多个,则有多个QQ好友信息。
回铃音由QQ控制播放。

(2)RING
方向:从QQ到设备
说明:呼入,振铃。参数子项依次为:


参数类型码

长度

值说明

8

1字节

RING,呼叫状态类型码:2

9

4字节

呼叫句柄(CallHandle),类型:DWORD

1

QQ号长度

QQ号,类型:以Null结尾的字符串

2

昵称长度

昵称,类型:以Null结尾的字符串

4(可选)

PSTN号码长度

PSTN号码,类型:以Null结尾的字符串

其中,呼叫句柄为QQ分配的唯一呼叫标识符;接下来的2个参数子项为呼入QQ好友信息;最后一个参数项为可选项,呼出的PSTN号码,该号码直接由呼叫方指定,本地QQ完成呼叫转移,转到PSTN号码上。如果RINGING带了“呼出的PSTN号码”,则本地不振铃,直接转移呼出;如果RINGING没带“呼出的PSTN号码”,则本地振铃。

(3)BUSY(针对转接盒设备)
方向:双向
说明:占线。参数子项依次为:


参数类型码

长度

值说明

8

1字节

BUSY,呼叫状态类型码:3

9

4字节

呼叫句柄(CallHandle),类型:DWORD

从QQ到设备:呼出,等待对方应答,且当对方的设备被PSTN占用时,则QQ向本地设备发送占线状态。
从设备到QQ:呼入,本地振铃,且当本地设备被PSTN占用时,则本地设备向QQ发送占线状态。

(4)ACCEPT
方向:从QQ到设备
说明:呼入或呼出,某方接受,双方进入通话状态。参数子项依次为:


参数类型码

长度

值说明

8

1字节

ACCEPT,呼叫状态类型码:4

9

4字节

呼叫句柄(CallHandle),类型:DWORD

(5)REJECT
方向:从QQ到设备
说明:呼入或呼出,某方拒绝。参数子项依次为:


参数类型码

长度

值说明

8

1字节

REJECT,呼叫状态类型码:5

9

4字节

呼叫句柄(CallHandle),类型:DWORD

(6)FINISH
方向:从QQ到设备
说明:呼入或呼出,通话结束,无论哪方发起。参数子项依次为:


参数类型码

长度

值说明

8

1字节

FINISH,呼叫状态类型码:6

9

4字节

呼叫句柄(CallHandle),类型:DWORD

(7)FAIL
方向:从QQ到设备
说明:呼出失败。参数子项依次为:


参数类型码

长度

值说明

8

1字节

FAIL,呼叫状态类型码:7

9

4字节

呼叫句柄(CallHandle),类型:DWORD

失败原因可能是,呼叫的用户不是QQ好友。

(8)HOLD(针对转接盒设备)
方向:从设备到QQ
说明:暂停通话,通话被切换到PSTN。参数子项依次为:


参数类型码

长度

值说明

8

1字节

HOLD,呼叫状态类型码:8

9

4字节

呼叫句柄(CallHandle),类型:DWORD

(9)RESUME(针对转接盒设备)
方向:从设备到QQ
说明:恢复通话,通话被切换到回QQ。参数子项依次为:


参数类型码

长度

值说明

8

1字节

RESUME,呼叫状态类型码:9

9

4字节

呼叫句柄(CallHandle),类型:DWORD

(10)MUTE
方向:从QQ到设备
说明:静音状态通知。参数子项依次为:


参数类型码

长度

值说明

8

1字节

MUTE,呼叫状态类型码:10

9

4字节

呼叫句柄(CallHandle),类型:DWORD

12

1字节

静音状态标志。1:静音打开;0:静音关闭

七、错误码定义

7.1 从QQ到设备――EVENT_QQAPI_ERROR

事件说明:从QQ到设备的错误通知
参数说明:WM_COPYDATA中的参数COPYDATASTRUCT结构说明详见2
dwData(事件码):20
lpData:如下表
cbData:消息参数总长度


参数类型码

长度

值说明

12

1字节

错误类型,类型:char

错误码定义:

八、参数类型码表

参数类型码

长度

值说明

1

QQ号长度

QQ号,类型:以Null结尾的字符串

2

昵称长度

昵称,类型:以Null结尾的字符串

3

速播号长度

速播号,类型:以Null结尾的字符串

4

PSTN号码长度

PSTN号码,类型:以Null结尾的字符串

5

设备名长度

音频设备名,类型:以Null结尾的字符串

6

4字节

音频设备的设备ID号,类型:DWORD

7

1字节

键值,详见4.3的“键值映射表”

8

1字节

呼叫状态的类型,类型:char,主要有:
(1)CONNECTING,呼叫状态类型码:1
(2)RING,呼叫状态类型码:2
(3)BUSY,呼叫状态类型码:3
(4)ACCEPT,呼叫状态类型码:4
(5)REJECT,呼叫状态类型码:5
(6)FINISH,呼叫状态类型码:6
(7)FAIL,呼叫状态类型码:7
(8)HOLD,呼叫状态类型码:8
(9)RESUME,呼叫状态类型码:9
(10)MUTE,呼叫状态类型码:10

9

4字节

呼叫句柄(CallHandle),类型:DWORD

10

1字节

通话人数,类型:char
注:通话人数会影响后续的参数子项,例如当通话人数为2,后面会跟两份的QQ用户信息。

11

1字节

状态变换的类型,类型:char,主要有:
(1)DIALNUM,状态变换类型码:1

12

1字节

静音状态标志。1:静音打开;0:静音关闭

13

1字节

错误类型,类型:char

posted @ 2006-04-24 12:59 我的梦想我的游戏 阅读(431) | 评论 (1)编辑 收藏

2006年4月21日 #

最近写了个代码,在UI线程中创建了一个窗口,然后在工作线程中修改了这个窗口中的一些数据,然后想用UpdateData(FALSE)来更新窗口的内容,结果在Debug版本下面就出现了Assert报错,说出错地方是wincore.cpp的888行和889行,就是这两句
  ASSERT((p = pMap->LookupPermanent(m_hWnd)) != NULL ||
   (p = pMap->LookupTemporary(m_hWnd)) != NULL);
  ASSERT((CWnd*)p == this);   // must be us
    我用MFC也没有多久,也不太熟悉,翻了翻资料,在http://support.microsoft.com/default.aspx?scid=kb;en-us;147578找到一篇文章,就是说MFC窗口跨线程的问题的,大概意思就是MFC的窗口是线程相关的,每个窗口的HandleMap是储存在线程相关的堆栈里面的(thread-local-storage (TLS) ),那这样我就理解了为什么上面两句ASSERT会出错了,线程环境都切换了当然线程堆栈的数据也就不一样了.
    这篇文章提供了两种修改方案:
    一种是用FromHandle来获得一个CWnd*,然后再调用UpdateData,这个方案我没有实验成功,结果是错虽然不报了,但是界面也没有被更新.
    另外一种是通过发消息的方法转到UI线程去处理.可以在窗口映射一个消息,比如ON_MESSAGE(WM_UPDATEDATA, OnUpdateData),然后用SendMessage(WM_UPDATEDATA, FALSE)传消息给窗口,窗口的消息处理肯定是在UI线程里面,这时候可以用
LRESULT CProtectPage::OnUpdateData(WPARAM wParam, LPARAM lParam)
{
 UpdateData(wParam);
 return 0;
}
来更新界面,实验是成功的,ASSERT就被消除了.
    还是有点疑惑,就是刚开始直接在工作线程中调用UpdateData(FALSE)的时候,虽然有ASSERT报错,但是结果还是正确的,似乎没有什么影响,不知道这个ASSERT到底意味着什么?
posted @ 2006-04-21 12:56 我的梦想我的游戏 阅读(939) | 评论 (3)编辑 收藏

仅列出标题