大亮 的个人资料程序员的救赎照片日志列表更多 工具 帮助

日志


11月18日

云南小结

自从云南之行归来,一直没时间来写一篇游记,
虽然,自认记忆力还可以,但是重温那每一天的行程和细节还是困难的。
只有罗列一些名词做为回忆的载体,才可以自私的梦回彩云之南。
多民族的体现:
白族(金花,阿朋G)纳西(胖金G,胖金M)彝族(阿诗玛,阿黑哥,白,花)香格里拉(骚多哩,猫多哩)
云南十八怪已经很难记得了。
只记得:什么三个蚊子一盘菜,鲜花论斤卖,躺在床上谈恋爱~~~
导游介绍的一些历史故事,却还能复述出来。
这次抱歉没有能图文相嵌,因为,我希望有空大家也要亲身去逛古街,搭讪下微笑的胖金妹,吃点特别的特色菜。
突然,发现自己在都市里变得像张白纸,而渴望去靠近五颜六色。
10月20日

[技]用xinetd系统服务来挂载socket服务端应用

1,准备好程序(本例程序或服务名为TVMsrv)
摘抄部分:
#if defined(__STDC__) || defined(__cplusplus)
main(int argc, char *argv[])
#else
main(argc, argv)
int argc;
char *argv[];
#endif
{
int sockfd,new_fd;
 sockfd=new_fd=0;
 WorkThread(&sockfd);
    close(sockfd);
    return 0;
}
2,在etc/services  中用vi在最后一行加入: TVMsrv             18023/tcp
3,在etc/xinetd.d/下建立文件TVMsrv,并加入如下内容:(注意服务名,文件名的统一)
service TVMsrv
{
        socket_type     = stream
        protocol        = tcp
        wait            = no
        user            = tbs
        server          = /home/tbs/bin/TVMsrv.sh
}
4,把启动服务程序的sh脚本,部署在相应描述的路径下。/home/tbs/bin/
当然,把编译好的程序也放在此目录下。(同时部署好供其使用的配置文件)
因为,脚本文件的最后一句,即是启动程序,例如:./TVMsrv $HOME/config/TVMsrv.cfg
5,然后,就等着准备客户端来测试吧,系统在帮助我们一直监听请求哟。
9月20日

[技]在linux下的配置(为适应ssh)

chkconfig --list | grep sshd    查看sshd服务在哪种级别下开启,建议only 3。

防火墙规则中必须允许sshd访问,可以:
1.清除防火墙规则,#iptables -F
2.#iptables -A INPUT -p tcp --dport 22 -j ACCEPT
   #iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT

9月10日

英语角使用---功夫熊猫台词整理

(turtle immortal)
  4.俗语说,
  过去的,已经过去了
  未来的,还未可知
  现在,却是上苍的礼赠
  那就是为什么今天是present(现在/礼物)
  There is a saying,
  Yesterday is history
  Tomorrow is a mystery
  But today is a gift
  That is why it’s called the present (the gift)
  1.往往在逃避命运的路上,却与之不期而遇(in other words when we afraid of sth,than sth may come true)
  One meets its destiny on the road he takes to avoid it
  5.世间无巧合
  There are no accidents.(every accident happenned with many conditions,we should pay more attendtion to)
  10.我私家汤的绝密食材,就是…什么都没有。
  认为它特别,它就特别了。
  The secret ingredient of my secret ingredient soup is...nothing.
  To make something special ,you just have to believe it’s special.
  2.你的思想就如同水,我的朋友,当水波摇曳时,很难看清,不过当它平静下来,答案就清澈见底了.(let us know the process or rule thing goes,another famous guy of old china use to said the same kind of this idiom 浊者自浊,清者自清----老子.)
  Your mind is like this water, my friend , when it is agitated ,it becomes difficult to see ,but if you allow it to
settle , the answer becomes clear.
______________________________________________________________________________________________________________  
  (background)
  8.师傅:那你为什么不退出呢?
  你知道我一直想把你赶走,
  可你还是留下来了。
  Why didn’t you quit ? you know I was trying to get rid of you
  but you stayed
  阿宝:是啊,我留下来了。
  我留下来是因为每次你往我头上丢砖头,
  或说我难闻,这很伤我的心。
  可最伤我心的是,我每天努力练习,却还是这个我。
  我留下来,因为我以为,
  如果还有人能改变我,
  能让我焕然一新,
  那就是你--
  中国最伟大的功夫师父!
  Yes ,I stayed .
  I stayed ,because every time you threw up brick on the head
  or said I smelled ,it hurts.
  But it could never hurt more than I did everyday in my life just being me .
  I stayed ,because I thought ..
  If anyone could change me ,
  could make me not me ,
  it was you
  the greatest Kong Fu teacher in the whole of China!
________________________________________________________________________________________________________
  true warrior, but do not surrender真正的武士绝不放弃
  3.退出,不退出。做面条,不做面条。
  Quit don’t quit. Noodles don’t noodles.
  6.乌龟:是的,看着这棵树,
  我不能让树为我开花,
  也不能让它提前结果
  Yes ,look at this tree Chivu(师傅)
  I can not make it boloosm and suits me ,
  nor make it bear food before it’s time .
  师傅:但有些事情我们可以控制
  我可以控制果实何时坠落
  我还可以控制在何处播种
  那可不是幻觉 大师
  but there are things we can control
  I can control when the fruit will fall
  ... And I can control
  What time to seed
  That is not illusion , Master
  乌龟:是啊 不过无论你做了什么
  那个种子还是会长成桃树
  你可能想要苹果 或桔子
  可你只能得到桃子
  那个种子还是会长成桃树
  Yes, but no matter what you do,
  That seed will grow to be a peach tree
  You may wish for an Apple or an orange
  But you will get a peach
  师傅:可桃子不能打败太郎
  But peache can not defeate Tai Long
  乌龟:也许它可以的 ,如果你愿意引导它、滋养它、相信它。
  Maybe it can if you are willing to guide it , to nuture it , to believe in it .
  7.你不能走,真的武士决不会退却you cannot leave ,real warrior never quits.
  9. 阿宝,天不遂人愿,
  况且这本不是天意,
  阿宝,忘了其它的事情,
  你的使命一直都在向你召唤。
  我们是面条家族,
  血管中流着这样的血。
  I'm sorry things didn’t work out …
  It’s just what it’s meant to be
  Paul ,forget everything else ,your destiny still awaits.
  We are Noodle folk
  Broth runs deep through our veins
8月27日

[技]转帖的VC dll引用的实用技巧

有关DLL的问题现在资料很多,但是很多人写DLL时经常出现调用程序无法找到相关的导出函数的问题,这里主要的原因是DLL在声明时出的问题。
在这里主要有两个问题,一个是调用约定的问题,一个是函数名修饰的问题,而这两个问题又是相互影响的。
一:声明为:extern "C" int __declspec(dllexport)add(int x, int y);
这种声明是强制用C语言方式进行修饰,且用C的默认约定,即__cdecl方式。这种方式编译产生的DLL中有一个导出函数:add,不加任何修饰。
二:声明为:extern "C" int __declspec(dllexport) __stdcall add(int x, int y);
这种声明是强制用C语言方式进行修饰,且用stdcall约定,这种方式编译产生的DLL中有一个导出函数:_add@8,即前面有“_”,后面加了参数长。
三:声明为:int __declspec(dllexport) __stdcall add(int x, int y);
这种声明不强制用C语言方式进行修饰,但是用stdcall约定,这种方式编译产生的DLL中有一个导出函数:?add@@YGHHH@Z。这个名字很怪,后面的不好理解。
四:声明为:int __declspec(dllexport) __cdecl add(int x, int y);
这种声明是不强制用C语言修饰,且用cdecl约定,这种方式编译产生的DLL中有一个导出函数:?add@@YAHHH@Z,注意看,和第三种方有一点不同。

实验一:显式调用方式调用DLL中的add函数。
#include <stdio.h>
#include <windows.h>
typedef  int(_stdcall *lpAddFun)(int, int); //宏定义函数指针类型
int main(int argc, char *argv[])
{
HINSTANCE hDll; //DLL句柄
lpAddFun addFun; //函数指针
hDll = LoadLibrary("1.dll");
if (hDll != NULL)
{
addFun = (lpAddFun)GetProcAddress(hDll, "add");
if (addFun != NULL)
{
int result = addFun(2, 3);
printf("%d", result);
}
else
printf("No Function");
}
else
printf("NO DLL");
FreeLibrary(hDll);
return 0;
}
方式一:调用成功。另外三种方式全部出错
实验二:隐式调用DLL中的add函数
#include <stdio.h>
#include <windows.h>
#pragma comment(lib,"1.lib")
extern "C" int __declspec(dllimport) add(int x, int y);//声明方式随着DLL中的声明方式改变
int main(int argc, char *argv[])
{
int result = add(2, 3);
printf("%d", result);
return 0;
}
方式一:调用成功。另外发现一个奇怪现象:在调用程序中
声明函数时extern "C" int __declspec(dllimport) add(int x, int y);
写作:extern "C" int __declspec(dllecprot) add(int x, int y);同样成功,将__declspec(…)去掉也同样成功。换句话说,在调用DLL的程序中,导入是没有必要加的。
方式二:调用成功。同样出现上面导入标识可以不加的现象。
方式三:调用成功,同样也出现上面导入标识可以不加的现象。
方式四:调用成功,同样也出现上面导入标识可以不加的现象。
总结:对于DLL导出函数声明的四种写法,在动态调用时,
声明成这样:extern "C" int __declspec(dllimport) add(int x, int y);是最好的,其它声明方式调用都没有成功。但是众所周知,windows默认的调用约定是stdcall方式,如果想别的语言能用DLL的话,最好是将调用约定写成stdcall方式,但是这种方式又不能动态调用。
在隐式调用时,四种声明方式都是可以的,只要调用者的声明方式和DLL声明时的方式一致即可。另外,在调用程序中对于导入的声明是可以去掉的,大量书籍中关于导入、导出的问题都是利用宏来处理的,如:在头文件中写作:
#ifdef DLL_FILE
extern "C" int __declspec(dllexport) add(int x, int y);
#else
extern "C" int __declspec(dlleximport) add(int x, int y);
这样这个头文件既可以用在DLL工程中,又可以用在调用程序中,但是经过实验发现,这个根本就没有必要,在调用者程序中不管是写作__declspce(dllexport)还是写作__declspec(dllimport)或者不写都能成功调用。
关于DEF文件
在DLL工程中引用DEF文件,内容如下:
LIBRARY 1
EXPORTS
add @ 1
通过depends查看导出函数全是add,但是隐式方式调用时,还是要求调用者的声明方式和DLL中声明方式相同。
对于动态调用实验结果:
方式一:成功。方式二:不成功,但是将函数指针改为typedef int(_stdcall *lpAddFun)(int, int);成功,即调用者要声明约定方式与DLL中声明的调用约定方式相同,否则报错。
方式三:同方式二,同样要将函数指针改为typedef int(_stdcall *lpAddFun)(int, int);才成功完成调用。
方式四:成功。
总结:通过DEF文件来导出函数,调用者同样也要声明相同的调用约定,即_stdcall或是_cdecl必须要相同,其中_cdecl是C语言默认方式。

静态引用:
1、将   mydll.dll   放在你的工程目录下。  
  2、将mydll.lib   放在你的工程目录下。  
  3、Project-->Add   to   project-->Files-->mydll.lib  
  4、在你的工程的MyPrjHeader.h文件加上:  
      extern   "C"   __declspec(dllimport)   int   Max(int,   int);  
  5、在你的工程的.cpp文件种调用:  
      #include   "MyPrjHeader.h"  
  main()  
  {  
      int   i;  
      int   Input_1,Input_2;  
      Input_1=10,Input_2=20;  
      i=Max(Input_1,Input_2);     //Max   为MyDll.dll里面的函数  
      cout<<i<<endl;  
      return   0;  
  }  
8月26日

[技]RIA的学习笔记1

闲的无聊,研究一下被我搁置很久的技术flash ria。(因为一直在观望,以待它成熟)
下了几个小工具,买了本书,开啃。
按功能划分:
(开发类)
flex builder 的长处在于可视化的mxml编辑,然而,复杂的菜单和各种应用的集成,让它显的有点臃肿。智能提示度高于FD,比如对event的支持,并且经过配置得当,可以跟踪断点。当多平台应用开发时,首选,当然,熟悉eclips的就必须的了,对开发的支持是挺强大的。是java族的宠儿。
flash devolop 开源(需要安装.net framework,JRE,FlexSDk),对于各种工具的接口和语言版本的支持都很好,插件式的配置,让开发者的思路清晰,调试方便(虽无断点,但可以trace)。顺便提句,它和.net暧昧。
(前台类)
不用说,flash cs4 和flash player10是比较合适的,但是在现有版本的FD中调试时,得使用现有的9.0.
(后台数据类)
这个不用多说,各种平台都有支持,包括数据库,目前对偶来说,还没有发言权。
要想深入了解,得研究一个用例,或开发个东东。后台用.net2.0,数据层可以由access或xml应用,毕竟,服务器和空间是现成的,且部署也可以少些麻烦。
8月20日

读每一条后,都请停顿思考十秒

1.现在女人真伟大。不知不觉肚子大、有了孩子没有爸!
2.小时候我们把玩具当朋友、长大了朋友拿我们当玩具。
3.你不能让所有的人满意,因为不一定所有的都是人。
4.人生就象卫生纸、没事尽量少扯、!
5.有老公怎么的? 有守门员球还进呢!
6.谁是谁老公? 都他妈临时工!
7.如果你看到面前的阴影,别怕,那是因为你的背后有阳光!
8.踏遍青楼人未老,请用汇仁肾宝
9.最穷无非讨饭、不死终会出头
10.时间是最好的老师,但遗憾的是——最后他把所有的学生都弄死了
11.别总拿你那老百姓的身份给我讲述那黑社会的故事 !
    你再牛逼百度咋搜索不到你呢?
    你再有劲你能憋住尿吗?
12.在任何状况下,不能玩弄别人,玩人必被人玩。
    你再有心眼,也不是最厉害的那个。
13.世界上最动听的话不是我爱你,而是你的肿瘤是良性的!
14.唾沫是用来数钞票的,而不是用来讲道理的
15.不该看的不看,不该说的不说,不该听的不听,不该想的不想,

    请专心致志的打你的酱油
16.男人的谎言可以欺骗女人一夜      女人的谎言可以欺骗男人一生

17.如果可能的话,更强一些,宁可强的让人羡慕,也不能弱得让人可怜!

18.世界上唯一不用努力就能得到的只有年龄!

19.不要吹牛逼、请把牛逼还给牛、因为牛也需要性生活!

20.大起大悲看清自己、 大起大落看清朋友。

21.我们只有一个地球,所以大家要爱护地球;

    地球上只有一个我,所以大家也要爱护我!

22.有钱不一定有道、敢摸不一定敢草。

23.开心了就笑,不开心了就过会儿再笑

24.名花虽有主、我来松松土。 名花有主,锄头无情...

25.向新朋友介绍女友时,请搂着她的腰,而不是站在一旁用手指点

26.走的最快的是最美的风景 伤的最深的是最真的感情

27.人生最大的悲哀,并不是在于你得不到或者失去的,而是你根本不知道你自己要的是什么!

28.长大后之所以这么努力、只是因为小时候吹过的牛逼!

29. 所谓成功的女人就是白天特NB,晚上B特N

30.假如有个人愿在自己身边,就算没有任何语言只是在身边,我也觉得是一种幸福,即使失去了一切,只要停下脚步看一下四周,一定会有某个人在你看得见的地方。请别伤心、不要绝望,无论如何也请别忘记,自己决不是孤单一人的.


31.在你头上拉屎的未必是敌人 把你从屎堆拉出来的未必是朋友

32.我不能做到我所希望的一切,但是我应该做好我可以做到的一切.

33.有 尿 当 尿 直 须 尿.莫 等 无 尿 空 抖 鸟

34.无论什么时候打电话,摘起话筒的时候请微笑,因为对方能感觉到.

35.上帝给了我们七情六欲,我们却把它们变成了色情和暴力

36.拥有一颗知足的心,知足者常乐。若想得到快乐,就别让自己过得无精打采,想要获得快乐,不是增加财富,而是降低欲望。

37.找一个你爱聊的人结婚 , 因为当年龄大了以后,你会发觉喜欢聊天是一个人最大的优点。

38.只要锄头舞的好,哪有墙角挖不倒。

39.至今为止,地球仍在我的脚下.

40.心若没有栖息的地方,到哪里都是在流浪!

41.不要相信接吻时从不闭眼的伴侣。

42.最好的关系存在于对别人的爱胜于对别人的索求之上。

43.没能耐的看人装逼,有能耐的跟人装逼

44.虽然我不在江湖,但是江湖有我的传说

45.人不可以把钱带进坟墓。  但钱可以把人带进坟墓。

46.废话是人际关系的第一句

47.看透别说透、继续做朋友。

48.吸引住男人的办法就是让他一直得不到;吸引女人的办法正好相反,就是让她一直满足。

49.男人,上半身是修养,下半身是本质;女人,上半身是诱饵,下半身是陷阱。

50.在街上看美女,目光高一点就是欣赏,目光低一点就是流氓。

51.女孩买很多很多漂亮衣服穿,就是为了吸引男孩的目光,但男孩想看的,却是不穿衣服的女孩。

52.男人都喜欢江山,是因为他们觉得只有整个江山才能让他们的女人心动

53.小人物的时间是最不值钱的 他可以和一个菜贩为了两毛钱而斤斤计较

54.当我们把情感更多的 放在 友情 爱情上  可往往最后 能让你感动的 只有亲情

55.所谓忠诚、只是因为背叛的筹码不够!

56.你叫我滚,我滚了,你叫我回来,对不起滚远了。


57. 想知道一个人的内心缺少什么,不看别的,就看他炫耀什么。想知道一个人自卑什么,不看别的,就看他掩饰什么
8月14日

[技]vc应用笔记-----表示层开发小技巧

表示层开发相关:
1)和dsp项目文件同名会有一个rc文件,一个aps文件,一个clw文件(当然后三个都是配套的当然挂接到dsp就不必一对一了,是N个“三多”对一)
2)在XXXdlg为名的文件系中(h,cpp),要做到类名统一(包括注释,大写的注释等,这很重要)
3)在member variable中,要想出显radio的控件名在control ids 列表的话,必须为控件设置group,并且都是int,value而非control.(同组可选的话,只设1控件的变量,group属性)dialog初始化时设置控件变量为-1,在initdialog方法控件变量设为1或者0,后加UpdateData(FALSE);。
4)UpdateData(FALSE);是指把此行以上的设置,更新到控件上,出效果。至于另外一情况,自己猜喽。
5)(CWnd *)GetDlgItem(IDC_READMAGNET)->EnableWindow(TRUE);//让一个控件可不可用的代码
技巧:
1)要想程序里支持CString,需要在StdAfx.cpp里加上如下的内容:
// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//
#if !defined(AFX_STDAFX_H__E54A5A52_F7D8_4655_8279_F870675B0230__INCLUDED_)
#define AFX_STDAFX_H__E54A5A52_F7D8_4655_8279_F870675B0230__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN  // Exclude rarely-used stuff from Windows headers
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxole.h>         // MFC OLE classes
#include <afxodlgs.h>       // MFC OLE dialog classes
#include <afxdisp.h>        // MFC Automation classes
#endif // _AFX_NO_OLE_SUPPORT

#ifndef _AFX_NO_DB_SUPPORT
#include <afxdb.h>   // MFC ODBC database classes
#endif // _AFX_NO_DB_SUPPORT
#ifndef _AFX_NO_DAO_SUPPORT
#include <afxdao.h>   // MFC DAO database classes
#endif // _AFX_NO_DAO_SUPPORT
#include <afxdtctl.h>  // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>   // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__E54A5A52_F7D8_4655_8279_F870675B0230__INCLUDED_)
7月14日

[技]itoa与atoi的详析

C语言提供了几个标准库函数,可以将任意类型(整型、长整型、浮点型等)的数字转换为字符串。以下是用itoa()函数将整数转 换为字符串的一个例子:

# include <stdio.h>
# include <stdlib.h>

void main (void)
{
int num = 100;
char str[25];
itoa(num, str, 10);
printf(\"The number ’num’ is %d and the string ’str’ is %s. \\n\" ,
num, str);
}

itoa()函数有3个参数:第一个参数是要转换的数字,第二个参数是要写入转换结果的目标字符串,第三个参数是转移数字时所用 的基数。在上例中,转换基数为10。10:十进制;2:二进制...
itoa并不是一个标准的C函数,它是Windows特有的,如果要写跨平台的程序,请用sprintf。 
是Windows平台下扩展的,标准库中有sprintf,功能比这个更强,用法跟printf类似: 

char str[255]; 
sprintf(str, \"%x\", 100); //将100转为16进制表示的字符串。 

下列函数可以将整数转换为字符串:
----------------------------------------------------------
函数名 作 用
----------------------------------------------------------
itoa() 将整型值转换为字符串
itoa() 将长整型值转换为字符串
ultoa() 将无符号长整型值转换为字符串

一  atoi     把字符串转换成整型数
例程序:
#include <ctype.h>
#include <stdio.h>
int atoi (char s[]);

int main(void )
{   
char s[100];
gets(s);
printf(\"integer=%d\\n\",atoi(s));
return 0;
}
int atoi (char s[])
{
int i,n,sign;
for(i=0;isspace(s[i]);i++)//跳过空白符
       ;
sign=(s[i]==’-’)?-1:1;
if(s[i]==’+’||s[i]==’ -’)//跳过符号
       i++;
for(n=0;isdigit(s[i]);i++)
       n=10*n+(s[i]-’0’);//将数字字符转换成整形数字
return sign *n;
}
二        itoa      把一整数转换为字符串
例程序:
#include <ctype.h>
#include <stdio.h>
void       itoa (int n,char s[]);
//atoi 函数:将s转换为整形数
int main(void )
{   
int n;
char s[100];
printf(\"Input n:\\n\");
scanf(\"%d\",&n);
         printf(\"the string : \\n\");
         itoa (n,s);
return 0;
}
void itoa (int n,char s[])
{
int i,j,sign;
if((sign=n)<0)//记录符号
       n=-n;//使n成为正数 [Page]
         i=0;
do{
       s[i++]=n%10+’0’;//取下一个数字
}while ((n/=10)>0);//删除该数字
if(sign<0)
       s[i++]=’-’;
s[i]=’\\0’;
for(j=i;j>=0;j--)//生成的数字是逆序的,所以要逆序输出
       printf(\"%c\",s[j]);
}
7月9日

[技]VC++学习笔记转帖

VC++中UpdateData()函数的使用

UpdateData(FALSE)与UpdateData(TRUE)是相反的过程
UpdateData(FALSE)是把程序中改变的值更新到控件中去
UpdateData(TRUE)是把在控件中输入的值更新到你的变量中去 TRUE ===> 控件 -〉数据成员
FALSE ===> 数据成员 -〉 控件
比如你的一个编辑框控件c_Edit与变量s_Edit相关联
在程序中你用了
s_Edit="CSDN"
但是你在编辑框中输入"NDSC"
如果你用的是UpdateData(FALSE)的话你的编辑框内容将是“CSDN”
如果你用的是UpdateData(TRUE)的话 s_Edit将变成“NDSC”如要让m_edit的内容立即生效
UpdateData(FALSE);
m_edit.UpdateWindow();//这句不能少,否则不会立即生效修正:如要让m_edit的内容立即生效
UpdateData(FALSE);
UpdateWindow();//这句不能少,否则不会立即生效
EDIT控件没有UpdateWindow这个成员函数,所以直接使用
例如:
m_name="";
m_mima="";
UpdateData(FALSE);
UpdateWindow();
============================
UpdateData(true);//用于将屏幕上控件中的数据交换到变量中。
UpdateData(false);//用于将数据在屏幕中对应控件中显示出来。
当你使用了ClassWizard建立了控件和变量之间的联系后:当你修改了变量的值,而希望对话框控件更新显示,就应该在修改变量后调用UpdateData(FALSE);如果你希望知道用户在对话框中到底输入了什么,就应该在访问变量前调用UpdateData(TRUE)。
二、关于编辑框的赋值和取值
向编辑框中赋值和取值时:
1、建一个 控制型的变量,如m_edit1,用CWnd的SetWindowText() 和GetWindowText()来赋值和取值。
m_Edit1.SetWindowText("Hello");
或者GetDlgItem(IDC_EDIT1)->SetWindowText(str);
2、建立一个控制型的变量,如m_edit1,用SetDlgItemText()和GetDlgItemText()来赋值和取值
CString Str="Hello":
m_edit1.SetDlgItemText(IDC_EDIT1,str);
2、直接建一个 数值形的变量 如m_strEdit; 用 UpdateData()来控制得到变量,还是更新变量。
//取值
UpdateData(TRUE);
CString buf = m_Edit1;
//赋值
m_Edit1="ok!";
UpdateData(FALSE);
————————————————————————————————————————————————————————————————————————

如何设置窗口的初始尺寸 
在将应用程序类(CxxAPP)的 InitInstance() 函数中加入:
m_pMainWnd->SetWindowPos(NULL,x,y,Width,Height,SWP_NOMOVE);
Width为窗口宽度,Height为窗口高度
SWP_NOMOVE表示忽略位置(x,y)。 
如:

让窗口居中显示 
以下两种方法可任选其一: 
①在应用程序类(CxxxApp)的 InitInstance() 函数中加入:
②在主框架类(MainFrm.cpp)的OnCreate()函数中加入:
CenterWindow( GetDesktopWindow() );
如:如何修改窗口标题 
窗口标题一般形式为:文档标题 - 程序标题 
1、设置文档标题: 
在文档类(CxxxDoc)的OnNewDocument()函数中加入语句:SetTitle("文档名");
如:TextEditorDoc.cpp:①可删除Debug文件夹和Release文件夹;
②原则上还可删除主文件夹中所有图标为 的文件,包括.aps、.ncb、.opt、.plg等文件,它们都能在编译时重建。但一般.clw不要删除,它可能导致ClassWizard不好用。



控件
如何隐藏和显示控件 
用CWnd类的函数BOOL ShowWindow(int nCmdShow)可以隐藏或显示一个控件。 
例1:
CWnd *pWnd;
pWnd = GetDlgItem( IDC_EDIT1 ); //获取控件指针,IDC_EDIT为控件ID号
pWnd->ShowWindow( SW_HIDE ); //隐藏控件
例2:
CWnd *pWnd;
pWnd = GetDlgItem( IDC_EDIT1 ); //获取控件指针,IDC_EDIT为控件ID号
pWnd->ShowWindow( SW_SHOW ); //显示控件

按钮的使能与禁止 
用ClassWizard的Member Variables为按钮定义变量,如:m_Button1;

m_Button1.EnableWindow(true); 使按钮处于允许状态
m_Button1.EnableWindow(false); 使按钮被禁止,并变灰显示

改变控件的大小和位置 
用CWnd类的函数MoveWindow()或SetWindowPos()可以改变控件的大小和位置。 
void MoveWindow(int x,int y,int nWidth,int nHeight);
void MoveWindow(LPCRECT lpRect);
第一种用法需给出控件新的坐标和宽度、高度;
第二种用法给出存放位置的CRect对象;
例:
CWnd *pWnd;
pWnd = GetDlgItem( IDC_EDIT1 ); //获取控件指针,IDC_EDIT1为控件ID号
pWnd->MoveWindow( CRect(0,0,100,100) ); //在窗口左上角显示一个宽100、高100的编辑控件
SetWindowPos()函数使用更灵活,多用于只修改控件位置而大小不变或只修改大小而位置不变的情况:
BOOL SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);
第一个参数一般设为NULL;
x、y控件位置;cx、cy控件宽度和高度;
nFlags常用取值:
SWP_NOZORDER:忽略第一个参数;
SWP_NOMOVE:忽略x、y,维持位置不变;
SWP_NOSIZE:忽略cx、cy,维持大小不变;
例:
CWnd *pWnd;
pWnd = GetDlgItem( IDC_BUTTON1 ); //获取控件指针,IDC_BUTTON1为控件ID号
pWnd->SetWindowPos( NULL,50,80,0,0,SWP_NOZORDER | SWP_NOSIZE ); //把按钮移到窗口的(50,80)处
pWnd = GetDlgItem( IDC_EDIT1 );
pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER | SWP_NOMOVE ); //把编辑控件的大小设为(100,80),位置不变
pWnd = GetDlgItem( IDC_EDIT1 );
pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER ); //编辑控件的大小和位置都改变
以上方法也适用于各种窗口。
——————————————————————————————————————————————————————————————————————

 VC学习笔记1:按钮的使能与禁止

      用ClassWizard的Member Variables为按钮定义变量,如:m_Button1;
      则
      m_Button1.EnableWindow(true); 使按钮处于允许状态
      m_Button1.EnableWindow(false); 使按钮被禁止,并变灰显示


      VC学习笔记2:控件的隐藏与显示

      用CWnd类的函数BOOL ShowWindow(int nCmdShow)可以隐藏或显示一个控件。

      例1:
      CWnd *pWnd;
      pWnd = GetDlgItem( IDC_EDIT1 );    //获取控件指针,IDC_EDIT为控件ID号
      pWnd->ShowWindow( SW_HIDE );    //隐藏控件

      例2:
      CWnd *pWnd;
      pWnd = GetDlgItem( IDC_EDIT1 );    //获取控件指针,IDC_EDIT为控件ID号
      pWnd->ShowWindow( SW_SHOW );    //显示控件

      以上方法常用于动态生成控件,虽说用控件的Create函数可以动态生成控件,但这种控件很不好控制,所以用隐藏、显示方法不失为一种替代手段。


      VC学习笔记3:改变控件的大小和位置

      用CWnd类的函数MoveWindow()或SetWindowPos()可以改变控件的大小和位置。

      void MoveWindow(int x,int y,int nWidth,int nHeight);
      void MoveWindow(LPCRECT lpRect);
      第一种用法需给出控件新的坐标和宽度、高度;
      第二种用法给出存放位置的CRect对象;
      例:
      CWnd *pWnd;
      pWnd = GetDlgItem( IDC_EDIT1 );    //获取控件指针,IDC_EDIT1为控件ID号
      pWnd->MoveWindow( CRect(0,0,100,100) );    //在窗口左上角显示一个宽100、高100的编辑控件

      SetWindowPos()函数使用更灵活,多用于只修改控件位置而大小不变或只修改大小而位置不变的情况:
      BOOL SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int
      cy,UINT nFlags);
      第一个参数我不会用,一般设为NULL;
      x、y控件位置;cx、cy控件宽度和高度;
      nFlags常用取值:
      SWP_NOZORDER:忽略第一个参数;
      SWP_NOMOVE:忽略x、y,维持位置不变;
      SWP_NOSIZE:忽略cx、cy,维持大小不变;
      例:
      CWnd *pWnd;
      pWnd = GetDlgItem( IDC_BUTTON1 );    //获取控件指针,IDC_BUTTON1为控件ID号
      pWnd->SetWindowPos( NULL,50,80,0,0,SWP_NOZORDER | SWP_NOSIZE );   
      //把按钮移到窗口的(50,80)处
      pWnd = GetDlgItem( IDC_EDIT1 );
      pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER | SWP_NOMOVE );   
      //把编辑控件的大小设为(100,80),位置不变
      pWnd = GetDlgItem( IDC_EDIT1 );
      pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER );    //编辑控件的大小和位置都改变
      以上方法也适用于各种窗口。


      VC学习笔记4:什么时候设定视中控件的初始尺寸?

      我在CFormView的视中加入了一个编辑控件,在运行时使它充满客户区,当窗口改变大小时它也跟着改变。
      改变控件尺寸可以放在OnDraw()函数中,也可放在CalcWindowRect()函数中,当窗口尺寸发生变化时,它们都将被执行,且CalcWindowRect()函数先于OnDraw()函数,下例是在CalcWindowRect()函数中修改控件尺寸。
      重载VIEW类的CalcWindowRect函数,把设定控件的尺寸的语句加入这个函数中。
      例:
      void CMyEditView::CalcWindowRect(LdivCT lpClientRect, UINT nAdjustType)
      {
          // TODO: Add your specialized code here and/or call the base class

          CFrameWnd *pFrameWnd=GetParentFrame(); //获取框架窗口指针

          CRect rect;
          pFrameWnd->GetClientRect(&rect); //获取客户区尺寸

          CWnd *pEditWnd=GetDlgItem(IDC_MYEDIT); //获取编辑控件指针,IDC_MYEDIT为控件ID号
          pEditWnd->SetWindowPos(NULL,0,0,rect.right,rect.bottom-50,SWP_NOMOVE |
      SWP_NOZORDER); //设定控件尺寸,bottom-50是为了让出状态条位置。

          CFormView::CalcWindowRect(lpClientRect, nAdjustType);
      }


      VC学习笔记5:单选按钮控件(Ridio Button)的使用

      一、对单选按钮进行分组:
      每组的第一个单选按钮设置属性:Group,Tabstop,Auto;其余按钮设置属性Tabstop,Auto。

      如:
      Ridio1、Ridio2、Ridio3为一组,Ridio4、Ridio5为一组

      设定Ridio1属性:Group,Tabstop,Auto
      设定Ridio2属性:Tabstop,Auto
      设定Ridio3属性:Tabstop,Auto

      设定Ridio4属性:Group,Tabstop,Auto
      设定Ridio5属性:Tabstop,Auto

      二、用ClassWizard为单选控件定义变量,每组只能定义一个。如:m_Ridio1、m_Ridio4。

      三、用ClassWizard生成各单选按钮的单击消息函数,并加入内容:

      void CWEditView::OnRadio1()
      {
          m_Ridio1 = 0;    //第一个单选按钮被选中
      }

      void CWEditView::OnRadio2()
      {
          m_Ridio1 = 1;    //第二个单选按钮被选中
      }

      void CWEditView::OnRadio3()
      {
          m_Ridio1 = 2;    //第三个单选按钮被选中
      }

      void CWEditView::OnRadio4()
      {
          m_Ridio4 = 0;    //第四个单选按钮被选中
      }

      void CWEditView::OnRadio5()
      {
          m_Ridio4 = 1;    //第五个单选按钮被选中
      }

      四、设置默认按钮:
      在定义控件变量时,ClassWizard在构造函数中会把变量初值设为-1,只需把它改为其它值即可。
      如:
      //{{AFX_DATA_INIT(CWEditView)
      m_Ridio1 = 0;    //初始时第一个单选按钮被选中
      m_Ridio4 = 0;    //初始时第四个单选按钮被选中
      //}}AFX_DATA_INIT


      VC学习笔记6:旋转控件(Spin)的使用

      当单击旋转控件上的按钮时,相应的编辑控件值会增大或减小。其设置的一般步骤为:
      一、在对话框中放入一个Spin控件和一个编辑控件作为Spin控件的伙伴窗口,
      设置Spin控件属性:Auto buddy、Set buddy integer、Arrow keys
      设置文本控件属性:Number

      二、用ClassWizard为Spin控件定义变量m_Spin,为编辑控件定义变量m_Edit,定义时注意要把m_Edit设置为int型。

      三、在对话框的OnInitDialog()函数中加入语句:
      BOOL CMyDlg::OnInitDialog()
      {
          CDialog::OnInitDialog();
         
          m_Spin.SetBuddy( GetDlgItem( IDC_EDIT1 ) );    //设置编辑控件为Spin控件的伙伴窗口
          m_Spin.SetRange( 0, 10 );    //设置数据范围为0-10
          return TRUE;
      }

      四、用ClassWizard为编辑控件添加EN_CHANGE消息处理函数,再加入语句:
      void CMyDlg::OnChangeEdit1()
      {
          m_Edit = m_Spin.GetPos();    //获取Spin控件当前值
      }

      OK!


      VC学习笔记7:程序结束时保存文件问题

      在文档-视图结构中,用串行化自动保存文件在各种VC书上都有介绍。现在的问题是我不使用串行化,而是自己动手保存,当点击窗口的关闭按钮时,如何提示并保存文档。

      用ClassWizard在文档类(CxxDoc)中添加函数CanCloseFrame(),再在其中加入保存文件的语句就可以了。
      注:要保存的数据应放在文档类(CxxDoc)或应用程序类(CxxApp)中,不要放在视图类中。

      例:
      //退出程序
      BOOL CEditDoc::CanCloseFrame(CFrameWnd* pFrame)
      {
          CFile file;
          if(b_Flag)    //b_Flag为文档修改标志,在修改文档时将其置为True
          {
              int t;
              t=::MessageBox(NULL,"文字已经改变,要存盘吗?","警告",
                      MB_YESNOCANCEL | MB_ICONWARNING);    //弹出提示对话框
              if(t==0 || t==IDCANCEL)
                  return false;
              if(t==IDYES)
              {
                  CString sFilter="Text File(*.txt)|*.txt||";
                  CFileDialog m_Dlg(FALSE,"txt",NULL,OFN_HIDEREADONLY |
      OFN_OVERWRITEPROMPT,(LPCTSTR)sFilter,NULL);    //定制文件对话框

                  int k=m_Dlg.DoModal();    //弹出文件对话框
                  if(k==IDCANCEL || k==0)
                      return false;
                  m_PathName=m_Dlg.GetPathName();    //获取选择的文件路径名
                 
                  file.Open(m_PathName,CFile::modeCreate | CFile::modeWrite);
                  file.Write(m_Text,m_TextLen);    //数据写入文件
                  file.Close();
              }
          }
          return CDocument::CanCloseFrame(pFrame);
      }


      VC学习笔记8:UpdateData()

      对于可以接收数据的控件,如编辑控件来说,UpdateData()函数至关重要。当控件内容发生变化时,对应的控件变量的值并没有跟着变化,同样,当控件变量值变化时,控件内容也不会跟着变。
      UpdateData()函数就是解决这个问题的。

      UpdateData(true);把控件内容装入控件变量
      UpdateData(false);用控件变量的值更新控件

      如:有编辑控件IDC_EDIT1,对应的变量为字符串m_Edit1,
      1、修改变量值并显示在控件中:
      m_Edit1 = _T("结果为50");
      UpdateData(false);
      2、读取控件的值到变量中:
      用ClassWizard为IDC_EDIT1添加EN_CHANGE消息处理函数,
      void CEditView::OnChangeEdit1()
      {
          UpdateData(true);
      }

6月18日

Big Day

      
 

[技]c++子类继承和调用父类的构造方法

 

     1.如果子类没有定义构造方法,则调用父类的无参数的构造方法,.

2.如果子类定义了构造方法,不论是无参数还是带参数,在创建子类的对象的时候,首先执行父类无参数的构造方法,然后执行自己的构造方法。

3.如果子类调用父类带参数的构造方法,可以通过super(参数)调用所需要的父类的构造方法,切该语句做为子类构造方法中的第一条语句

4.如果某个构造方法调用类中的其他的构造方法,则可以用this(参数),切该语句放在构造方法的第一条.

说白了:原则就是,先调用父亲的.(没有就默认调,有了就按有的调,反正只要有一个就可以了.)

package test;

class Father{

String s = "Run constructor method of Father";

public Father(){

   System.out.println(s);

}

public Father(String str){

   s= str;

   System.out.println(s);

}

}

class Son extends Father{

String s= "Run constructor method of son";

public Son(){

   //实际上在这里加上super(),和没加是一个样的

   System.out.println(s);

}

public Son(String str){

   this();//这里调用this()表示调用本类的Son(),因为Son()中有了一个super()了,所以这里不能再加了。

   s = str;

   System.out.println(s);

}

public Son(String str1, String str2){

   super(str1+" "+str2);//因为这里已经调用了一个父类的带参数的super("---")了,所以不会再自动调用了无参数的了。

   s = str1;

   System.out.println(s);

}

}

public class MyClass9 {

public static void main(String[] args){

   Father obfather1 = new Father();

   Father obfather2 = new Father("Hello Father");

   Son obson1 = new Son();

   Son obson2 = new Son("hello son");

   Son obson3 = new Son("hello son","hello father");

  

}

}

===============

结果:

Run constructor method of Father

Hello Father

Run constructor method of Father

Run constructor method of son

Run constructor method of Father

Run constructor method of son

hello son

hello son hello father

hello son

6月16日

[技]ansistring,string,char[]和char*之间那点事儿

方法一:
    AnsiString temp = g_dev->PartStatusData(part_id);
    strncpy(status_data,temp.c_str(),len);
    return len < temp.Length()?len:temp.Length();
方法二:
    string s("127.0.0.1");
    char c[50];
    strcpy(c,s.c_str());
方法三:
  char *p=s.GetBuffer(50);
  strcpy(buf,p);
 
PS:
CString>Format()相当于:  
  char   aaa[65536*65536];  
  CString   bbb;  
  sprintf(aaa,"%x%d.......",a,c.......);  
  bbb=aaa;  

strlen(char *str) : 求字符串长度
strcpy(char *dest, char *src) : 把src拷贝到dest
strcat(char *dest, char *src) : 把src连接到dest后面
strcmp(char *s1, char *s2) : 按照各个字符(ascii)比较s1和s2,相等则返回0,否则返回ascii相减的结果
strstr(char *s1, char *s2) : 在s1中查找s2,返回找到的位置,若找不到则返回NULL 

C中格式字符串的一般形式为: [标志][输出最小宽度][.精度][长度]类型 其中方括号[]中的项为可选项。各项的意义介绍如下:

1.类型类型字符用以表示输出数据的类型,其格式符和意义下表所示:
表示输出类型的格式字符       格式字符意义
d                 以十进制形式输出带符号整数(正数不输出符号)
o                 以八进制形式输出无符号整数(不输出前缀O)
x                 以十六进制形式输出无符号整数(不输出前缀OX)
u                 以十进制形式输出无符号整数
f                 以小数形式输出单、双精度实数
e                 以指数形式输出单、双精度实数
g                 以%f%e中较短的输出宽度输出单、双精度实数
c                 输出单个字符
s                 输出字符串
2.标志
标志字符为-、+、#、空格四种,其意义下表所示:
标志格式字符      标 志 意 义
-          结果左对齐,右边填空格
+          输出符号(正号或负号)空格输出值为正时冠以空格,为负时冠以负号
#          对c,s,d,u类无影响;对o类, 在输出时加前缀o; 对x类,在输出时加前缀0x;对e,g,f 类当结果有小数时才给出小数点
3.输出最小宽度
用十进制整数来表示输出的最少位数。 若实际位数多于定义的宽度,则按实际位数输出, 若实际位数少于定义的宽度则补以空格或0。
4.精度
精度格式符以“.”开头,后跟十进制整数。本项的意义是:如果输出数字,则表示小数的位数;如果输出的是字符, 则表示输出字符的个数;若实际位数大于所定义的精度数,则截去超过的部分。
5.长度
长度格式符为h,l两种,h表示按短整型量输出,l表示按长整型量输出。
void main(){
int a=15;
float b=138.3576278;
double c=35648256.3645687;
char d=’p’;
printf("a=%d,%5d,%o,%x\n",a,a,a,a);
printf(
"b=%f,%lf,%5.4lf,%e\n",b,b,b,b);
printf(
"c=%lf,%f,%8.4lf\n",c,c,c);
printf(
"d=%c,%8c\n",d,d);
} a<--15
b<--138.3576278
c<--35648256.3645687
d<--’p’ main()
{
int a=29;
float b=1243.2341;
double c=24212345.24232;
char c=’h’
printf(
"a=%d,%5d,%o,%x\n",a,a,a,a);
printf(
"b=%f,%lf,%5.4lf,%e\n",b,b,b,b);
printf(
"c=%lf,%f,%8.4lf\n",c,c,c);
printf(
"d=%c,%8c\n",d,d);
}
本例第七行中以四种格式输出整型变量a的值,其中“%5d ”要求输出宽度为5,而a值为15只有两位故补三个空格。 第八行中以四种格式输出实型量b的值。其中“%f”和“%lf ”格式的输出相同,说明“l”符对“f”类型无影响。“%5.4lf”指定输出宽度为5,精度为4,由于实际长度超过5故应该按实际位数输出,小数位数超过4位部分被截去。第九行输出双精度实数,“%8.4lf ”由于指定精度为4位故截去了超过4位的部分。第十行输出字符量d,其中“%bc ”指定输出宽度为8故在输出字符p之前补加7个空格。
5月18日

制度-工具-文明

伟大的制度,成就伟大的文明
春秋之秦就是例证。没有商鞅,李斯等法家挂相变革,就没有一统。
而如今,公司是社会个体的舞台。制度也呈现多元化(文化,等纷纷成为代名词)
现在,我要说工具,这将是一个更形象的时代标识。我们依然可以理解它为制度的代名词。
工具,从石器到铁,从冷兵器再到热兵器,再到现在的网络,我们的制度也在相应的变化。
所以,谁拥有最先进的工具,就会得到领先的理念,自然崛起,有资本去侵略(可以理解为暴发户脑中的任何想法)。
所以,我们需要擦亮眼睛,发现伟大的工具就变得重要。君子善假于物也。
在新公司里,让我眼前一亮的工具有:、、、、、、、、
SVN,VPP,PD,当然也可以算上VA助手
前三个是管理,抽象设计工具,对它的重视,也说明了,我正在过渡成为架构师或者说是PM。
一个项目中有几千行代码,几百个表,几十个类,十几个页面,却有时却只有一张表,一张图。
就像是金字塔的结构。最具挑战和创意的工作事实上来自于顶端的设计。
 
 
————————————————————————————
远程登陆的技巧:
mstsc /console /v:192.168.0.58:3389
VC学习:
MFC的事件处理,setcursior和loadcursior,strtok方法,
DDX-DDV和update(true/false)的配合使用来绑定成员变量到页面控件值。
三种dll的原理和应用
5月6日

解读恶作剧之吻2

一向不理偶像剧的我,近日,闲看了几眼台剧《恶2》,虽然看的少,但以管窥豹,可以一斑。
猜一下导演之意。


从元畅和依晨的婚礼中发现,海峡两岸的婚俗,竟然保持如此相同,
此外,中国人骨子里表达感情的含蓄和内敛也让两岸的观众有着共鸣。
而导演安排的那一对儿很哈日的情侣,是用于专门破坏元畅和依晨蜜月的。其中的那个MM,好像就是日本人,她时不时一句日文,发嗲腔,见色起义,然后又想和依晨玩换伴侣等~~~

虽然这只是一部偶像剧,但这个剧在向观众传达什么呢,尤其是在大环境下,大陆和台湾隔舍不断的血脉,是否也在受着日本对台湾的“暧昧支持”的冲击呢?

剧中的男女一号用信任和纯朴打动着我,爱情路上的干扰都被我们可爱的依晨和定力深厚的元畅化解。
什么是主旋律,什么是小插曲,
导演所要表达的,也许我们都已经理解了,所以,我更喜欢台偶剧多于韩偶剧。

4月28日

[技]转帖:C#调用VC中DLL的数据类型转换映射表

handle---------IntPtr

hwnd-----------IntPtr

char *----------string

int * -----------ref int

int &-----------ref int

void *----------IntPtr

unsigned char *-----ref byte

Struct需要在C#里重新定义一个Struct

CallBack回调函数需要封装在一个委托里,delegate static extern int FunCallBack(string str);

注意在每个函数的前面加上public static extern +返回的数据类型,如果不加public ,函数默认为私有函数,调用就会出错。

在C#调用C++ DLL封装库时会出现两个问题:

1. 数据类型转换问题
2. 指针或地址参数传送问题
    首先是数据类型转换问题。因为C#是.NET语言,利用的是.NET的基本数据类型,所以实际上是将C++的数据类型与.NET的基本数据类型进行对应。
    例如C++的原有函数是:
int __stdcall FunctionName(unsigned char param1, unsigned short param2)
    其中的参数数据类型在C#中,必须转为对应的数据类型。如:
[DllImport(“ COM DLL path/file ”)]
extern static int FunctionName(byte param1, ushort param2)
    因为调用的是__stdcall函数,所以使用了P/Invoke的调用方法。其中的方法FunctionName必须声明为静态外部函数,即加上 extern static声明头。我们可以看到,在调用的过程中,unsigned char变为了byte,unsigned short变为了ushort。变换后,参数的数据类型不变,只是声明方式必须改为.NET语言的规范。
    我们可以通过下表来进行这种转换:
Win32 Types
CLR Type
char, INT8, SBYTE, CHAR
System.SByte
short, short int, INT16, SHORT
System.Int16
int, long, long int, INT32, LONG32, BOOL , INT
System.Int32
__int64, INT64, LONGLONG
System.Int64
unsigned char, UINT8, UCHAR , BYTE
System.Byte
unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR , __wchar_t
System.UInt16
unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT
System.UInt32
unsigned __int64, UINT64, DWORDLONG, ULONGLONG
System.UInt64
float, FLOAT
System.Single
double, long double, DOUBLE
System.Double
    之后再将CLR的数据类型表示方式转换为C#的表示方式。这样一来,函数的参数类型问题就可以解决了。
    现在,我们再来考虑下一个问题,如果要调用的函数参数是指针或是地址变量,怎么办?
    对于这种情况可以使用C#提供的非安全代码来进行解决,但是,毕竟是非托管代码,垃圾资源处理不好的话对应用程序是很不利的。所以还是使用C#提供的ref以及out修饰字比较好。
    同上面一样,我们也举一个例子:
int __stdcall FunctionName(unsigned char &param1, unsigned char *param2)
    在C#中对其进行调用的方法是:
[DllImport(“ file ”)]
extern static int FunctionName(ref byte param1, ref byte param2)
    看到这,可能有人会问,&是取地址,*是传送指针,为何都只用ref就可以了呢?一种可能的解释是ref是一个具有重载特性的修饰符,会自动识别是取地址还是传送指针。
    在实际的情况中,我们利用参数传递地址更多还是用在传送数组首地址上。
如:byte[] param1 = new param1(6);
    在这里我们声明了一个数组,现在要将其的首地址传送过去,只要将param1数组的第一个元素用ref修饰。具体如下:
[DllImport(“ file ”)]
extern static int FunctionName(ref byte param1[1], ref byte param2)
4月24日

[技]整理的VC数据类型说明

BOOL       A   Boolean   value.   
BSTR       A   32-bit   character   pointer.   
BYTE       An   8-bit   integer   that   is   not   signed.  
COLORREF       A   32-bit   value   used   as   a   color   value.  
DWORD       A   32-bit   unsigned   integer   or   the   address   of   a   segment   and   its   associated   offset.  
WORD=1/2*DWORD(哈,偶比较懒,自己悟) 
LONG       A   32-bit   signed   integer.  
LPARAM       A   32-bit   value   passed   as   a   parameter   to   a   window   procedure   or   callback   function.  
LPCSTR       A   32-bit   pointer   to   a   constant   character   string.  
LPSTR       A   32-bit   pointer   to   a   character   string.  
LPCTSTR       A   32-bit   pointer   to   a   constant   character   string   that   is   portable   for   Unicode   and   DBCS.  
LPTSTR       A   32-bit   pointer   to   a   character   string   that   is   portable   for   Unicode   and   DBCS.  
LPVOID       A   32-bit   pointer   to   an   unspecified   type.  
LRESULT       A   32-bit   value   returned   from   a   window   procedure   or   callback   function.  
UINT       A   16-bit   unsigned   integer   on   Windows   versions   3.0   and   3.1;   a   32-bit   unsigned   integer   on   Win32.  
WNDPROC       A   32-bit   pointer   to   a   window   procedure.  
WORD       A   16-bit   unsigned   integer.  
WPARAM       A   value   passed   as   a   parameter   to   a   window   procedure   or   callback   function:   16   bits   on   Windows   versions   3.0   and   3.1;   32   bits   on   Win32
——————————

我们先定义一些常见类型变量借以说明

int i = 100;
long l = 2001;
float f=300.2;
double d=12345.119;
char username[]="程佩君";
char temp[200];
char *buf;
CString str;
_variant_t v1;
_bstr_t v2;

一、其它数据类型转换为字符串


短整型(int)
itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制
itoa(i,temp,2); ///按二进制方式转换
长整型(long)
ltoa(l,temp,10);
浮点数(float,double)
用fcvt可以完成转换,这是MSDN中的例子:
int decimal, sign;
char *buffer;
double source = 3.1415926535;
buffer = _fcvt( source, 7, &decimal, &sign );
运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
decimal表示小数点的位置,sign表示符号:0为正数,1为负数
CString变量
str = "2008北京奥运";
buf = (LPSTR)(LPCTSTR)str;
BSTR变量
BSTR bstrValue = ::SysAllocString(L"程序员");
char * buf = _com_util::ConvertBSTRToString(bstrValue);
SysFreeString(bstrValue);
AfxMessageBox(buf);
delete(buf);
CComBSTR变量
CComBSTR bstrVar("test");
char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
AfxMessageBox(buf);
delete(buf);

_bstr_t变量
_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用
_bstr_t bstrVar("test");
const char *buf = bstrVar;///不要修改buf中的内容
AfxMessageBox(buf);


通用方法(针对非COM数据类型)
用sprintf完成转换
char  buffer[200];
char  c = '1';
int   i = 35;
long  j = 1000;
float f = 1.7320534f;
sprintf( buffer, "%c",c);
sprintf( buffer, "%d",i);
sprintf( buffer, "%d",j);
sprintf( buffer, "%f",f);

二、字符串转换为其它数据类型
strcpy(temp,"123");

短整型(int)
i = atoi(temp);
长整型(long)
l = atol(temp);
浮点(double)
d = atof(temp);
CString变量
CString name = temp;
BSTR变量
BSTR bstrValue = ::SysAllocString(L"程序员");
...///完成对bstrValue的使用
SysFreeString(bstrValue);

CComBSTR变量
CComBSTR类型变量可以直接赋值
CComBSTR bstrVar1("test");
CComBSTR bstrVar2(temp);

_bstr_t变量
_bstr_t类型的变量可以直接赋值
_bstr_t bstrVar1("test");
_bstr_t bstrVar2(temp);


三、其它数据类型转换到CString
使用CString的成员函数Format来转换,例如:


整数(int)
str.Format("%d",i);
浮点数(float)
str.Format("%f",i);
字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值
str = username;
对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。

四、BSTR、_bstr_t与CComBSTR


CComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。
char *转换到BSTR可以这样:
BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib
SysFreeString(bstrValue);
反之可以使用
char *p=_com_util::ConvertBSTRToString(b);
delete p;
具体可以参考一,二段落里的具体说明。

CComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。
特别是_bstr_t,建议大家使用它。


五、VARIANT 、_variant_t 与 COleVariant


VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。
对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:
VARIANT va;
int a=2001;
va.vt=VT_I4;///指明整型数据
va.lVal=a; ///赋值

对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:

Byte bVal;  // VT_UI1.
Short iVal;  // VT_I2.
long lVal;  // VT_I4.
float fltVal;  // VT_R4.
double dblVal;  // VT_R8.
VARIANT_BOOL boolVal;  // VT_BOOL.
SCODE scode;  // VT_ERROR.
CY cyVal;  // VT_CY.
DATE date;  // VT_DATE.
BSTR bstrVal;  // VT_BSTR.
DECIMAL FAR* pdecVal  // VT_BYREF|VT_DECIMAL.
IUnknown FAR* punkVal;  // VT_UNKNOWN.
IDispatch FAR* pdispVal;  // VT_DISPATCH.
SAFEARRAY FAR* parray;  // VT_ARRAY|*.
Byte FAR* pbVal;  // VT_BYREF|VT_UI1.
short FAR* piVal;  // VT_BYREF|VT_I2.
long FAR* plVal;  // VT_BYREF|VT_I4.
float FAR* pfltVal;  // VT_BYREF|VT_R4.
double FAR* pdblVal;  // VT_BYREF|VT_R8.
VARIANT_BOOL FAR* pboolVal;  // VT_BYREF|VT_BOOL.
SCODE FAR* pscode;  // VT_BYREF|VT_ERROR.
CY FAR* pcyVal;  // VT_BYREF|VT_CY.
DATE FAR* pdate;  // VT_BYREF|VT_DATE.
BSTR FAR* pbstrVal;  // VT_BYREF|VT_BSTR.
IUnknown FAR* FAR* ppunkVal;  // VT_BYREF|VT_UNKNOWN.
IDispatch FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH.
SAFEARRAY FAR* FAR* pparray;  // VT_ARRAY|*.
VARIANT FAR* pvarVal;  // VT_BYREF|VT_VARIANT.
void FAR* byref;  // Generic ByRef.
char cVal;  // VT_I1.
unsigned short uiVal;  // VT_UI2.
unsigned long ulVal;  // VT_UI4.
int intVal;  // VT_INT.
unsigned int uintVal;  // VT_UINT.
char FAR * pcVal;  // VT_BYREF|VT_I1.
unsigned short FAR * puiVal;  // VT_BYREF|VT_UI2.
unsigned long FAR * pulVal;  // VT_BYREF|VT_UI4.
int FAR * pintVal;  // VT_BYREF|VT_INT.
unsigned int FAR * puintVal;  //VT_BYREF|VT_UINT.


_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
使用时需加上#include
例如:
long l=222;
ing i=100;
_variant_t lVal(l);
lVal = (long)i;


COleVariant的使用与_variant_t的方法基本一样,请参考如下例子:
COleVariant v3 = "字符串", v4 = (long)1999;
CString str =(BSTR)v3.pbstrVal;
long i = v4.lVal;


六、其它一些COM数据类型

根据ProgID得到CLSID
HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);
CLSID clsid;
CLSIDFromProgID( L"MAPI.Folder",&clsid);

根据CLSID得到ProgID
WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID);
例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID
LPOLESTR pProgID = 0;
ProgIDFromCLSID( CLSID_IApplication,&pProgID);
...///可以使用pProgID
CoTaskMemFree(pProgID);//不要忘记释放

七、ANSI与Unicode
Unicode称为宽字符型字串,COM里使用的都是Unicode字符串。

将ANSI转换到Unicode
(1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);
(2)通过MultiByteToWideChar函数实现转换,例如:
char *szProgID = "MAPI.Folder";
WCHAR szWideProgID[128];
CLSID clsid;
long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));
szWideProgID[lLen] = '\0';
(3)通过A2W宏来实现,例如:
USES_CONVERSION;
CLSIDFromProgID( A2W(szProgID),&clsid);
将Unicode转换到ANSI
(1)使用WideCharToMultiByte,例如:
// 假设已经有了一个Unicode 串 wszSomeString...
char szANSIString [MAX_PATH];
WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL );
(2)使用W2A宏来实现,例如:
USES_CONVERSION;
pTemp=W2A(wszSomeString);
八、其它

对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:
LPARAM lParam;
WORD loValue = LOWORD(lParam);///取低16位
WORD hiValue = HIWORD(lParam);///取高16位


对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:
WORD wValue;
BYTE loValue = LOBYTE(wValue);///取低8位
BYTE hiValue = HIBYTE(wValue);///取高8位


两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)
LONG MAKELONG( WORD wLow, WORD wHigh );
WPARAM MAKEWPARAM( WORD wLow, WORD wHigh );
LPARAM MAKELPARAM( WORD wLow, WORD wHigh );
LRESULT MAKELRESULT( WORD wLow, WORD wHigh );


两个8位的数据(BYTE)合成16位的数据(WORD)
WORD MAKEWORD( BYTE bLow, BYTE bHigh );


从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值
COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
例如COLORREF bkcolor = RGB(0x22,0x98,0x34);


从COLORREF类型的颜色值得到RGB三个颜色值
BYTE Red = GetRValue(bkcolor); ///得到红颜色
BYTE Green = GetGValue(bkcolor); ///得到绿颜色
BYTE Blue = GetBValue(bkcolor); ///得到兰颜色


九、注意事项
假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" ) 。

4月19日

程序员说

刚才想了一下此文的题目,突然想到中学课本中有个《捕蛇者说》,内容不太记得,反正,我就效仿一下吧。
 
开始时,程序员是技术至上的,认为只要技术牛,吃便天下,后来发现,重要不是技术,而是沟通技巧和做人。
开始时,程序员是祟尚开发语言,什么C,java,C++等,孰强孰弱,华山论剑,后来发现,重要的不是语言是思想,是算法。
开始时,程序员喜欢用花哨的IDE,什么VC,Builder,VS2005等,感觉会用快捷键和特别配置,很厉害,很酷,
后来发现,重要的是会用UML,visio这才是王道,牛人只用这些就OK了,
相信更高级的人,只用PPT了,或者啥也不用,只用秘书~~~~~
哈~~~
4月9日

[技]非MFC类DLL的服务函数发布方式

甲方:A:是服务提供者(服务可以是函数···)
乙方:B:是服务使用者(调用DLL者)
 
方式一:
在A方定义服务函数的CPP文件引用的头文件外,应该有一个同名的.def文件,用来标识要提供给B的函数,这算是一种发布。
格式如下:
LIBRARY LIB//lib是CPP文件名
EXPORTS
add @ 1//add就是服务的方法名,它的序列为1,此处将对应B中的调用(addFun = (lpAddFun)GetProcAddress(hDll,MAKEINTRESOURCE(1));)
 
另一种发布方式:在A中头文件的服务函数定义时,在返回值前加上红字部分,extern "C" __declspec(dllexport)int add(int x,int y);
这样便可在B中,对应如下调用(addFun = (lpAddFun)GetProcAddress(hDll,"add");)
 
注:
当然以上的二种调用语句,位置都是在LoadLibrary和FreeLibrary的上下文中间。
除了服务函数外,还可以提供服务的全量变量,类等,但如果是用变量,则推荐使用_declspec(dllexport)的方式进行。