VC6工程项目改名

首先,网上找了个工具改名的,VCRename用了一下成功,注意新生成的目录中,dsw和dsp文件一定要改过来了。
然后,用新的改名后的工程编译出新程序。
但是,如果你的旧程序是个互斥的机制,即只能启动一个实例的情况。
那么,你会发现,虽然,你用改名工具把文件和工程都改了,但是新程序和改名前的程序不能同时启动。
差在哪里呢。
就是app_title.往细了说是,底层的m_pszAppname还在共同一个,并没有变化成功,所以把这个变量改名了,程序才不会被互斥的。那么什么会关联这个变量呢。就是资源文件。但有人说改名工具已经把资源文件的名字改了。可是其中的内容并没有变,这是原理了。
所以,打开资源文件的页签,找”String Table”.
在表格中找到,afx_ids_app_title 把它的值改名同于你的新名字,然后再编译后,新旧两程序同时可启动并不互斥了。

window开发之项目宏定义

转来一个文章,对VC6下项目建立和解决编译问题时,很有帮助。
常见的编译参数VC建立项目时总会定义”Win32″。控制台程序会定义”_CONSOLE”,否则会定义”_WINDOWS”。Debug版定义”_DEBUG”,Release版定义”NDEBUG”
  与MFC DLL有关的编译常数包括:
  _WINDLL 表示要做一个用到MFC的DLL
  _USRDLL 表示做一个用户DLL(相对MFC扩展DLL而言)
  _AFXDLL 表示使用MFC动态链接库的 regular DLL
  _AFXEXT 表示要做一个MFC扩展DLL
  所以:
  Regular, statically linked to MFC _WINDLL,_USRDLL
  Regular, using the shared MFC DLL _WINDLL,_USRDLL,_AFXDLL
  Extension DLL _WINDLL,_AFXDLL,_AFXEXT
Building Your DLL
When compiling regular DLLs that statically link to MFC, the symbols “_USRDLL” and “_WINDLL” must be defined. Your DLL code must also be compiled with the following compiler switches:
•/D_WINDLL      signifies the compilation is for a DLL
•/D_USRDLL      specifies you are building a regular DLL
When compiling regularDLLs that statically link to MFC, the symbols “_USR DLL” and”_WINDLL” must be defined. Your DLL code must also be compile dwith the following compiler switches:
When compiling regular DLLs that dynamicallylink to MFC, you must define t he above symbols and use the above compilerswitches. Additionally, the sy mbol “_AFXDLL” must be definedand your DLL code must be compiled with:
•/D_AFXDLL     specifies that you are building a regular DLL that dynamicall y links to MFC
The interfaces (APIs) between the application and the DLL must beexplicitlyexported. It is recommended that you define your interfaces to be lowbandw idth, sticking to C interfaces where possible. More direct C interfaces areeasi er to maintain than more complex C++ classes.
Place your APIs in aseparate header that can be included by both C and C++files (that way you won’tlimit your DLL customers to C++ programmers). Se e the header ScreenCap.h in theMFC Advanced Concepts sample DLLScreen Cap for an example. To export yourfunctions, enter them in theEXPORTSs ection of your moduledefinition file (.DEF) or include__declspec(dllexpor t)on yourfunction definitions. Use__declspec(dllimport)to import thesefunctions into the client executable.
You must add theAFX_MANAGE_STATEmacro at the beginning of all the e xportedfunctions in regular DLLs that dynamically link to MFC to set the curr ent modulestate to the one for the DLL. This is done by adding the followingline of codeto the beginning of functions exported from the DLL:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
WinMain->DllMain
The MFC library defines the standard Win32DllMain entry point that initializ es yourCWinAppderived object as in a normal MFC application. Placeall DLL-specific initialization in theInitInstancememberfunction as in a normal MFC application.

最近碰到问题是,一个静态库,没有编译成多线程选项,致使在console中使用正常,新建一个mfc app中使用就不成了。
提示了一堆和CTYPE.h中定义的pctype,timezone,mb_*类的错误。
后来,把静态库,用多线程重编译,并且,用“不定义所有宏”选项,置了一下,然后,静态库就可以被mfc exe来使用了,虽然库并不依赖MFC。当然,此前有winsock的重定义的问题。后来在stdafx.h中加了winsock2.h的引用后,就解决了。

VC6的环境小结

安装:
现在主要有win7,win10,但后者还没听说可以装成功。不过好在有虚机嘛。所以,只聊下win7的VC6安装。
VC6的安装源你总应该拿到,最好是SP6的。
如果是英文版本,安装会少些步骤,有一个是overwrite JIT setting的对话框,网查后我选择了否。
如果是中文版本,请寻找帖子,名为:彻底解决兼容问题:Windows 7下载安装 Visual C++ 6_0(VC6) 全程图解
一步步安装即可,VSS和MSDN都可跳过不安装。
最重要的就是插件了,这个才是彰显尊贵的手段。
filetool,wndtab,VA,VC6lineNumber
一个都不能少,全破解版(自己搜吧)。
配置:
1,用标准库,要注意<>的内容两边加空格 ,并且#pragma   warning(disable:4786)来屏闭VC6中的使用标准库的警告。
2,用C++运行程序时总是出现这个错误BSCMAKE: error BK1510 : corrupt .SBR file ‘.\Debug\StdAfx.sbr’,在C/C++—>gernal中取消生成浏览信息的选项。
3,PROJECT->SETING->C/C++->PREPROCESSOR->定义 _AFXDLL,也就是C/C++选项中定义了宏  用_AFCDLL 取代 USERDLL 能解决很多nafxcwn.lib开头的链接错误。
4,Link选项中ignore default lib,根据方式设定,手工加/NODEFAULTLIB:或者填库名。
5,VC6下导出类中的静态成员需要“壳子”才可以调用,而在VS2012中,却直接可用。当不同的环境生成的dll或客户端相互调用时,要注意字符集问题,VC6并不是unicode的。
6,要声明通用函数时,可以不加;在{}后面,但应该声明为static,这样可以避免重复定义的报错。
7,string 的split算法,replace,trim需要自己写算法,最后找到使用模板的。
8,在有unicode的项目中,在循环中使用W2A()可能会有报错,或者提示为,run-time check fail #2 stack …,内存操作越界之类,在VS2012中项目–C\C++设置中,改掉一个设置,“基本运行时检查”从“两者(/RTC1,等同于 /RTCsu) (/RTC1)”换成默认值。其实出现它的问题,还是在于使用scanf时,“%02x”的操作数组应该至少是3,要包含个’\0’的。
9,项目是要供别人调用的dll,要在配置中使用/MD.
10,要通过exe来调度dll时,要配置debug session和work directory
11,当出现外部链接错误时,要先检查link中的lib文件,是否存在于项目目录中。并不需要dll,因为只是链接步骤。
12,字符集问题,VC6是基于MBCS的(有宏定义,当然可以强制成unicode),对于中文用两字节,而字母和数字用一个字节。而VS201X,都是用unicode默认的,所以也就存在于宽字符的结构了,和一系列转来转来的操作。

tinyxml使用技巧

实在是好用呀,优点比如:
1,一次装载到内存,其它地方全用引用即可,一个小指针可以是一个元素,也可是一个节(内部很多子元素)。
2,不用管理元素的内存回收,我是没看源码,号称管理的很好。一个父元素删除,它包含的所有子都释放了。
3,api较少并且,一目了然。
遍历时基本就用三个算法:
1)同级的循环(没用遍历以防会误解包括子节点处理)
//pParent当然是父了
for (TiXmlNode *pSTATE = pParent->FirstChild( “STATE” ); pSTATE; pSTATE = pSTATE->NextSibling(“STATE” ))
{}
注意:要用TiXmlNode *结构,不要用TiXmlElement*
2)当同级的到了最后一个,NextSibling()会返回个空。这时你可以用跳了。
pParent->IterateChildren( pSTATE )
3)以上两个掌握了,就可以玩遍历了。不过,要注意,走到叶子节点时,要跳级。但如果你手工跳了,可能遍历会有重复情况。这时可以使用函数的静态变量喽。可以用静态变量记住父结点。可以用静态list来存放处理过的节点,跳过重复情况。示例代码如下:
void handleExportMap(TiXmlNode * pSrc)
{
if (!pSrc ) return;

static TiXmlNode *bodyItem;

if (“FRAME_BODY” == pSrc->ValueTStr())
{
bodyItem = pSrc ;
}
static TiXmlNode *curpItem;
int t = pSrc ->Type();
printf( “type %d \n” , t);

switch (t)
{
case TiXmlNode :: TINYXML_DOCUMENT:
printf( “Document” );
break ;

case TiXmlNode :: TINYXML_ELEMENT:
printf( “Element [%s]” , pSrc ->Value());
//
if (“CONTENT” == pSrc->ValueTStr())
{
curpItem = pSrc ;
}
if (“MAP” == pSrc->ValueTStr())
{
//跳过MAP的处理
pSrc = curpItem->IterateChildren(pSrc ->Parent());

if (!pSrc )
return ;
else
printf( “Element [%s]” , pSrc ->Value());
}
if (“STATE” == pSrc->ValueTStr() && pSrc == pSrc ->Parent()->LastChild())
{
//跳过STATE的处理
//map中的state
pSrc = curpItem->IterateChildren(pSrc ->Parent()->Parent());

if (!pSrc )
return ;
else
printf( “Element [%s]” , pSrc ->Value());
}

if (“ITEM” == pSrc->ValueTStr())
{

printf( “Element [%s]” , pSrc ->Value());

if (!pSrc ->NoChildren())
{
if (!bMoveItems(pSrc ))
return ;
}

} //end if (!pSrc->NoChildren())
if (“MESSAGE” == pSrc->ValueTStr())
{
curpItem = pSrc ;
if (!bMoveItems(pSrc ))
return ;
}
break ;

case TiXmlNode :: TINYXML_COMMENT:
printf( “Comment: [%s]” , pSrc ->Value());
break ;

case TiXmlNode :: TINYXML_UNKNOWN:
printf( “Unknown” );
break ;

case TiXmlNode :: TINYXML_TEXT:
printf( “Text: [%s]\n” , pSrc ->ToText()->Value());
break ;

case TiXmlNode :: TINYXML_DECLARATION:
printf( “Declaration” );
break ;
default :
break ;
}

if (pSrc ->NoChildren())
{
pSrc = pSrc ->NextSibling();

handleExportMap( pSrc );
}
else
{
//过滤,直到合法
while (pSrc = pSrc->FirstChild())
{
handleExportMap( pSrc );

}

}
}
在这个遍历的框架基础上,可以变化和设计出你的需求了,注意,要分化任务,只做遍历,和只做节点的处理,不要混在一起,不然,一个bug两三天呀。上面的bMoveItems就是当定位到了ITEM节点时,我调用其它的业务处理。因为,人只关注ITEM节点,所以它有一些子节点MAP或子子节点STATE,都在上面一一跳过了。

最后,附上“米”,好“下锅”,注意层次。
<?xml version=”1.0″ encoding=”UTF-8″ ?>
<!– edited with XMLSpy v2013 (http://www.altova.com) by () –>
<LINE ID=”11″ VERSION=”1″>
<FRAME_HEADER>
<ITEM ID=”system_id” LENGTH=”1″ CURPOS=”0″ />
<ITEM ID=”total_length” LENGTH=”2″ CURPOS=”1″ MAX_VALUE=”1025″ />
<ITEM ID=”multi_flag” LENGTH=”1″ CURPOS=”3″ DEFAULT=”0″ />
</FRAME_HEADER>
<FRAME_BODY>
<MESSAGE ID=”NETWORK_ALIVE_STATUS” TYPE=”1″ TRANS=”O2N”>
<ITEM ID=”message_length” LENGTH=”2″ CURPOS=”4″ DESC=”消息长度” MIN_VALUE=”13″ interal_index=”1″ />
<ITEM ID=”time” LENGTH=”4″ CURPOS=”6″ DESC=”时间” FORMAT=”HHMMSS” interal_index=”2″>
<MAP NID=”time” MODE=”1″ SAME=”Y” NINDEX=”2″ KEY=”time|6|4″ DESC=”时间” EX_CODE_KEY=”” />
</ITEM>
<ITEM ID=”version” LENGTH=”2″ CURPOS=”10″ DESC=”版本” DEFAULT=”01H” interal_index=”3″ />
<ITEM ID=”msg_id” LENGTH=”2″ CURPOS=”12″ DESC=”报文ID” interal_index=”4″ />
<CONTENT ID=”data0″ DEFAULT_LEN=”3″>
<ITEM ID=”line_id” LENGTH=”2″ CURPOS=”14″ DESC=”线路号” interal_index=”5″>
<MAP NID=”line_id” MODE=”1″ SAME=”Y” NINDEX=”5″ KEY=”line_id|14|2″ EX_CODE_KEY=”” />
</ITEM>
<ITEM ID=”status” LENGTH=”1″ CURPOS=”16″ DESC=”状态字节:1:代表与当前线路号的信息源(server)连接正常;0:代表断开。” interal_index=”6″>
<MAP NID=”xt_pkg” MODE=”1″ SAME=”N” NINDEX=”6″ KEY=”xt_pkg|16|1″ EX_CODE_KEY=””>
<STATE ID=”11_STATUS_CODE_1″ RAWVALUE=”0x00″ HINT=”通信中断” SAME=”Y”>0x80</STATE>
<STATE ID=”11_STATUS_CODE_2″ RAWVALUE=”0x01″ HINT=”通信正常” SAME=”Y”>0x02</STATE>
</MAP>
</ITEM>
</CONTENT>
</MESSAGE>
<MESSAGE ID=”LOAD_DEVICE_STATUS” TYPE=”1″ TRANS=”N2O”>
<ITEM ID=”message_length” LENGTH=”2″ CURPOS=”4″ DESC=”消息长度” MIN_VALUE=”12″ interal_index=”1″ />
<ITEM ID=”time” LENGTH=”4″ CURPOS=”6″ DESC=”时间” FORMAT=”HHMMSS” interal_index=”2″ />
<ITEM ID=”version” LENGTH=”2″ CURPOS=”10″ DESC=”版本” DEFAULT=”01H” interal_index=”3″ />
<ITEM ID=”msg_id” LENGTH=”2″ CURPOS=”12″ DESC=”报文ID” interal_index=”4″ />
<CONTENT ID=”data0″ DEFAULT_LEN=”2″>
<ITEM ID=”line_id” LENGTH=”2″ CURPOS=”14″ DESC=”线路号” interal_index=”5″ />
</CONTENT>
</MESSAGE>
</MESSAGE>
</FRAME_BODY>
</LINE>

保存和另存,一个TiXmlDocument的SaveFile()函数就搞定了。
生成新的XML时,会用一个api就成了。parent->LinkEndChild(TiXmlNode *);根据不用我解释了吧。加同级,用parent()找父指针嘛。

北京工作居住证攻略

朝阳区人才的位置:三元桥,凤凰城附近
海淀区人才的位置:北京市海淀区西四环北路73号中关村人才发展中心
办理:
首先,你要把自己的证件都复印好,不用等待网络上的信息注册后再准备,但完税证明不要提前,因为有效期只有一个月。
但办这事的入口,还是你公司为你注册了帐号,然后,你就可以登陆并看到办理居住证的链接了。
然后,就是材料最后的准备阶段了,去开完税证明和公司行政打交道完成各种手续。
最后,在提交时,想要办小孩上学要注意随迁问题。住址和居住证跨区的小孩上学问题,需要向学校搞清楚。

年检:
这其实是公司人力的动作,每年四月,他们应该用他们的企业帐号登陆系统,做操作。

续证:
工作居住证到期的前后一个月,要在网上先申请,然后,要去所在区人才,柜台办理。又要拿一大堆打印的申请。

变更:
分公司,住址,随迁等种类变更。但重要的是公司变更吧。
本人下家也具有工作居住证的资质,所以,变更准备材料如下:
(只针对海淀人才)
1)居住证原件(这不用说吧)
2)关于为XXX同志办理《北京市工作居住证》聘用单位变更的申请———-网找模板,加盖公司章
3)聘用单位变更申请———–网找模板,是个人申请,所以不用公章
4)营业执照复印副本
5)离职证明原件+复印件———-注意复印件也要盖章,经办人签字(附句话:经本人同意与原件内容一致)
6)新公司的劳动合同原件+复印件———-注意复印件也要盖章,经办人签字 (附句话: 经本人同意与原件内容一致)
不用每页都有章,最好公司有复印件专用的方章,可以在首页和签字页盖章即可。

说什么诚信声明和进入系统打印申请表,这两项并不需要。
当你的申请被受理后,海淀人才就告诉我,两个月左右,登录看一下系统中办理的状态,如果是完成,那么,你有两个方式来取回自己的居住证。一,让公司人事去办事时顺便取到,二,自己打印一个介绍信,模板不好找,但当时,我把柜台的模板照了下来。这样,可以自己起草一个,找公司盖章,注意只好盖章后,拿这个介绍信才能自己取到。
注销:
也是公司人力的动作,当你想在新公司变更或重新办新的,或其它业务时,前公司应该给你注销先。
注销后,两个月内个人如果没有延期注销的动作,那么你的居住证生命线就over了

延期注销:
当你换的新公司试用期较长,或者暂时没公司,或者工作忙时,可以在注销的两个月最后几天,申请延期注销。
那么你就有了6个月的机动时间。当然,你要登陆系统,自己填写申请并提交。如果你的新公司比较确定,要在备注的内容里体现。据说这样
会不仅有6个月,即使长一些,也能救起证的生命线。提交成功就行,不用去柜台了。

以Qtreeview为例介绍Qt的model/view/item框架

因为,Qtreeview是层次容器,所以会复杂。尤其是加子行的时候。
首先,要找到是哪里加子行。有两个思路:位置索引还是item
1)用model的位置索引方式,定位到要加子行的QModelIndex.
2)用item方式,即后台以批量的list加树时,找到item的位置。
3)用model,如果后台的批量item加完就释放,若无从找到,有一个神器就是Model->itemFromIndex(myparent);这是索引和后台item的桥。
后两种方式归纳来看,也算是从item入手了,而且推荐都使用Item方式加子行,不然,可能会陷入到后台model和view中的QModelIndex的不同步,那个问题会让你乱套的。
然后,找到了加子行的点,就是要找方法了。
1)item->appendRow(传入item的list);
2)Model->insertRows(0, 1, myparent); // 添加一行,注意参数是QModelIndex,要理解树模型中子节点的索引机制
虽然,model有自己的appendRow函数,但是,加一行是没问题,分层次加子行时还是不行的。
而且,在分别使用item对象和QModelIndex对象的Data()和setData()时要注意,默认的role参数,一个是0,一个是257.这是绝对的坑儿。
不然,你设置了,总感觉设置的数据为空,不显示。role是一个新维度的概念,使用很方便,只要传入和调出控制好了,是一大神器。
resizecolumncontent也是个不错的技巧,可以在你设置了model后重新调用,根据内容适应宽度。
代码有点乱:但可以上两棵树,并且都有子行。

  //测试绑定线路报文内容到树控件
  QList <QStandardItem *> items;
  QList <QStandardItem *> childItems;
  for (int i = 0; i < 4; ++i)
  {
  QStandardItem *item = new QStandardItem( QString (“item L%0” ).arg(i));
  if (0 == i)
  item->setCheckable( true );
  items.push_back(item);
  }
  lineModel->appendRow(items);
  for (int i = 0; i < 4; ++i)
  {
  for (int i = 0; i < 4; ++i)
  {
  QStandardItem *item = new QStandardItem( QString (“L%0” ).arg(i));
  if (0 == i)
  item->setCheckable( true );
  childItems.push_back(item);
  }
  items.at(i)->appendRow(childItems);
  //lineModel->setItem(i, 0, childItems.at(i));
  }
  items.clear();
  childItems.clear();
  int iRow = -1;
  for (int i = 0; i < 4; ++i)
  {
  for (int i = 0; i < 3; ++i)
  {
  QStandardItem *item = new QStandardItem( QString (“item R%0” ).arg(i));
  if (0 == i)
  item->setCheckable( true );
  items.push_back(item);
  }
  //items.at(i)->appendRow(items);
  //normalModel->setItem(i, items.at(0));
  normalModel->appendRow(items);
  items.clear();
  iRow++;
  }
  //方式一,以setdata方式加子行
  //QModelIndex myparent = normalModel->index(iRow,0);
  // //myparent = normalModel->index(0, 0, myparent);
  // normalModel->insertRows(0, 1, myparent); // 添加一行
  // normalModel->insertColumns(0, 3, myparent); // 添加三列
  // ui.treeView_normal->reset();
  // ui.treeView_normal->setModel(normalModel);
  // ui.treeView_normal->update();
  // emit ui.treeView_normal->dataChanged(normalModel->index(0, 0), normalModel->index(0, 3, myparent));
  ////for (int i = 0; i<3; i++)
  ////{
  // QModelIndex index = normalModel->index(0, 0, myparent);
  // normalModel->setData(index, “kk”);
  // ui.treeView_normal->reset();
  // ui.treeView_normal->setModel(normalModel);
  // ui.treeView_normal->update();
  // emit ui.treeView_normal->dataChanged(normalModel->index(0, 0), index);
  // normalModel->insertColumns(0, 1, myparent); // 添加一列
  // index = normalModel->index(0, 1, myparent);
  // normalModel->setData(index, “ll”);
  // emit ui.treeView_normal->dataChanged(normalModel->index(0, 0), index);
  // ui.treeView_normal->update();
  // ui.treeView_normal->setModel(normalModel);
  // normalModel->insertColumns(0, 1, myparent); // 添加一列
  // index = normalModel->index(0, 2, myparent);
  // normalModel->setData(index, “mm”);
  // ui.treeView_normal->setModel(normalModel);
  // ui.treeView_normal->update();
  // //ui.treeView_normal->paintEvent()
  // emit ui.treeView_normal->dataChanged(normalModel->index(0, 0), index);
  // ui.treeView_normal->reset();
  ////}
  //myparent = lineModel->index(0,0);
  //QModelIndex tmp = lineModel->index(0, 0,myparent);
  // ui.treeView_line->setCurrentIndex(tmp);
  //方式二,以model的setitem方式加行
  QModelIndex myparent = normalModel->index(iRow, 0);
  for (int i = 0; i < 3; ++i)
  {
  QStandardItem *item = new QStandardItem( QString (“R%0” ).arg(i));
  if (0 == i)
  item->setCheckable( true );
  childItems.push_back(item);
  }
  //items.at(i)->appendRow(childItems);
  QStandardItem * tmp = normalModel->itemFromIndex(myparent);
  tmp->appendRow(childItems);
  childItems.clear();
  //normalModel->setItem(iRow, 0, childItems.at(0));
  QStandardItem *item = new QStandardItem( QString (“RE%0” ).arg(0));
  childItems.push_back(item);
  item = new QStandardItem ( QString( “RE%0” ).arg(1));
  childItems.push_back(item);
  item = new QStandardItem ( QString( “RE%0” ).arg(2));
  childItems.push_back(item);
  normalModel->appendRow(childItems);

自由行泰国

自由行者干货吐血奉献:
感觉用倒叙的时间串起来可读性高。

行程章节:
健议,6-10天,选2-3地,6天以内,可以专注1城。很多老外一处一呆就是一个月。租车租房租泰妹已成文化,一盘水果一帮朋友喝到深夜。直到出行前,多看穷游攻略,锦囊啥的。没确定机票前,并不需要订太多景点的票和接机出租啥的,前者用app提前一天解决,点对点的接驳在当地解决吧,可以议价嘛。

首先,倒数半年吧,拿护照买亚航票赶打折是必须的,购时要额外去除保险的点选,因为那是默认选中的坑,不要在意big sort的积分,它是事后才积上去的。对于行李和机上餐可按需选择。注意因为是低价机票,所以不包含这些的。
确定了行程,可以细化你每一天的安排了。是一个城市,还是要飞来飞去?由于本人家人5人10天。所以,舍弃了久仰的清迈。因为,考虑到小孩和老人,不能以旅行团一样的安排,所以,曼谷+芭提雅+泰南的苏梅+涛岛,事实证明大家很满意。

曼谷是购物之都,大皇宫父母只呆了不到半小时,就吵着要逛街。所以,在最后两天在曼谷购物,不然,提着大小包去玩可是很辛苦。
芭提雅离曼谷近,大巴2小时,方便随时,并且沿海热闹。并不细说,我老婆最钟爱此地。但并不上岛,因为后面有好戏。
苏梅+岛,四天的深度感受,才能让大家忘记北方的寒冷和帝都的#¥¥%#。

飞前倒数一个半月,去搞定签证,在网上找可信的旅行社带办,一人花费2百多吧。

倒数一周时,换外币,因为换币要提前预约的,不然,很可能白跑一趟,我是在中国银行柜台办理的,据说汇率低。
不用换太多美金,真用不上。甚至不用换。我在华夏卡里存了6K(号称每天第一次取钱免手续费,但好像至少会有50铢会被当地ATM扣)
具体的安排:
华夏存入6K
换美金1K(本人中间有马来西亚的transit,出关玩了半天,所以,其实应该直接换马币)
换泰铢4K
当然,要带信用卡喽

倒数第四天时,下淘宝单,买电话卡,happy-7day卡。虽然,电话功能只用了不超过五次,但随时上网帮了很多的忙。因为,要收发订单邮件的和各种app的使用。7天过期后本人找到服务点,加了两天的上网约110铢

倒数第三天,网上值机,打印登机牌,打印各种订单确认(住宿酒店确认,地址信息等)和地图资源(一般酒店大堂都提供)。把手机的旅行app整理到一个文件夹,下载最新版本,先登陆上所有出游app帐号,以防到时找不到帐号,影响大事。
本人的app介绍如下:(重要程度,由上至下)
google maps
booking.com
面包自由行
穷游
私人邮箱设置
亚航

途牛
携程
蚂蜂窝自由行

前四位很强大,他们会互相配合,这里要赞一下面包。我在面包上订了一个安通海洋公园和一个人妖秀,都是质量很高,前一天下单,第二天享受,当然,要拿确认邮件去享受了。当然有条件的话,可以打印出来。泰国的IT水平不高,找到愿意让你使用的打印机很难的。酒店的服务人员不会同意,因为上网有风险,并且电脑都为公用。而没有像中国一样的打印复印店的。所以,你只能找office了,幸好有好心的人帮助。我转发邮件给他,他打印出来。面包上的景点也都可以关联google导航定位。这样,离的近或打车前去,大可尽在掌握。
再有就是booking.com了,的确专业,对订单反应速度巨快,可以结合苹果的passbook。

文化章节:
喝白酒的人注意,泰国找不到白酒,并且,早餐很难找,因为,上午开店的很少。在寺庙不要吵,也不用交门票。

详细行程一览表:

地点/时间/逗留 源–目标机场 景点 事后总结(有血的教训)
北京/马来西亚 PEK—KUL 马来西亚–双子塔–central park–机场商圈 事实上到了central market玩了半天,吃了个饭。有一个30分钟的快轨klia2直达central.
马来西亚/曼谷 KUL–DMK 体验美食,然后休息 到达天黑了,入住,准备第二天一早出发芭提雅
曼谷/芭提雅 坐BTS至下面站之一:1)victoryment station|胜利纪念碑(阿怒烧瓦里拆)2)E7|曼谷市东站|Ekkamai|Eastern Bus Terminal,2号口出就是东站。注:租用面包车.汽车北站(Mo chit) 四方水上市场另一个响亮名字是杜拉拉水上市场(最好提前网购票)可以坐香蕉船,照相,购物,看表演。中午后人开始多,我们去早了。 事实上,酒店前台安排了前往芭提雅的家庭型车,5人一共2000铢
巴堤雅 原路返曼谷 东芭乐园,室内民俗表演,大象表演,骑大象,旅游车参观等。到当地后订房两晚,200人民币一晚,有游泳池,比较舒适。 在著名的红灯区街walking street的西北部找了个性价比很高的酒店,记往在海滩的外圈找,那里会便宜。吃海鲜,游泳,逛街(晚上去,你懂的)
芭提雅/曼谷 当地订房一晚,19,200人民币一晚 大巴车,坐到离廊曼机场近的站,在那里现找酒店,因为要赶飞机去苏梅,到曼后晚间逛了跳蚤市场,咋都咋(东西很多,但必须狠讲价,比MBK的价水份还大)
苏梅岛/20-22 DMK–NST车船联:大巴–>–
Donsak码头->—
Lipa Noi Pier(苏梅亚航集合地)–>-面包车->-酒店
查汶海滩(Chaweng Beach)、波普海滩(Borphut Beach)、拉迈海滩(Lamai Beach)和湄南海滩(Maenam Beach)。 海岛的房间紧张,所以用booking.com早下手了。海难上很热闹,水果很便宜。用面包app订了安通海洋公园,做快艇,浮潜,皮划艇,自助,实在是印象深刻,非常推荐。
龟岛(TAO)/23-24 nakhon si thammarat(NST) –bangkok-Don mueang(DMK)车船联:
酒店–>–Seatran pier->–Donsak pier–>–大巴->-机场-16:10->-FD3187–>-17:30-
潜水,南苑岛,mahead bea(海滩),购物街很多 岛上出租车很贵,要由酒店前台来叫。并且,按地图规划好下车地和游览路线。由于有孩子,不能去南苑岛和潜水。有几个购物区路线。逛的同时,看到了离岛的码头Seatran pier 那里有亚航的接待点,车船联票的入口。
龟岛/曼谷/24-26 DMK–KUL 大船–7座小巴–飞机 一天用来赶路,做大船不用很颠婆。有钱的可以从苏梅飞。
曼谷/北京 KUL–PEK 唐人街,泰拳,nana街 找到大皇宫附近的宾馆住下,第二天路线是,大皇宫,考山路,王权免税店,MBK,克里索普人妖秀。注意,去王权要拿两样东东,护照(本人全程随身)还有是打折地图(免费领于酒店前台,上面有打折卡的)。买的东东可以在机场退税。还有就是湄南河边的人妖秀了。风景和文化大餐。人妖秀很艺术,每个位子送一种自选饮品。第二天,飞京略

囧点:
1)买了个超标的箱子,只能托运,而又没买20kg的行李托运,在机场又要登机了,结果高价买了托运–600银子。
2)爸有个小军刀,老婆有些化妆品被安检拦了,幸好,有免费的寄存,等回来北京后,从机场拿走。
3)爸妈先抵泰国机场,对于入境卡拒填,他以为那个是落地签,语言又不通,真是难为他们了。 汇合后出了机场,打不到taxi,因为,机场很规范,有专门的打的通道,要排队,就一定有打表的taxi。
4)上了车,老爸习惯的往副驾驶一座,可是,司机就站在旁边,比划了半天,老爸往前一看,原来有方向盘。
5)注意,泰铢纸币的1K和100的特别相近,本人就大方的给了1K的小费。
6)由于经停马来西亚,本人换了马币,可返程时赶飞机,没有消费掉剩下的钱,结果,回国后发现中国银行不能换马币。结果,留做纪念了。还有若干泰铢硬币。

VS2013字符集小结

VS新版本打开旧项目,即当升级一个vcproject文件时,可能会涉及从“多字节字符集”(可能是utf-8)到unicode字符集的转换。
所以总结一下,代码端如何适应转换。

unicode字符集下,微软引入了一个宽字符集的概念(多讨厌)
所以,有些winapi就是以宽字符集来传参的。

第一类问题:messagebox()函数
所以字符串常量前,加一个L,即L“原来的字符串”;
L的意思是小端序。当为unicode时,长度要么1要么2(汉字),所以,再加上小端序,不会有歧义了。

第二类问题:strcpy()函数要求多字符集,事实此时的CSting已经入乡随俗了用了宽字符集,而直接强制转换就会出现让你头大的提示,
居然const char * 和 CString不等价了。

char SendBuf[512] = {0};
strcpy(SendBuf,strEdit); //CString参数strEdit,报错说不能转换CString到const char *
——————————–
办法一:用新的缓冲区放置,并且必须再转换一下。
char SendBuf[512] = {0};
strcpy(SendBuf,( const char *)strEdit.GetBuffer());
办法二:复杂,此时要做的是把“变质的”CString给救回来。

char SendBuf[512] = {0};
wchar_t temp[512];
MultiByteToWideChar(CP_ACP, NULL, (LPCCH)strEdit.GetBuffer(), 512, temp, 512);
strcpy(SendBuf,(const char *)temp);
m_Conn.Send(SendBuf,strlen(SendBuf));

第三类问题,atoi转int:
把atoi换成_ttoi即可,这是神器,在啥字符集下,都可编译。

第四类问题,CString->std::string 举例如下:
CString strMfc=“test“;
std::string strStl;

#ifdef _UNICODE

USES_CONVERSION
strStl=W2A(strMfc.LockBuffer());

strMfc.UnlockBuffer();

#else

strStl = strMfc.GetBuffer(0);

strMfc.ReleaseBuffer();

#endif
—————-
有时,CString可以做为桥梁,把乱码的UTF-8字符串转成string打印正确。思路是先用下面的函数转换乱码,再把返回的CString转string.
CString UTF8toUnicode(const char* utf8Str, UINT length)
{
CString unicodeStr;
unicodeStr = _T(“”);
if (!utf8Str)
return unicodeStr;

if (length == 0)
return unicodeStr;

//转换
WCHAR chr = 0;

for (UINT i = 0; i std::string 举例如下
BSTR bstrTest = ::SysAllocString(L”Test”);

_bstr_t bstr_t(bstrTest);

std::strStl = bstr_t;

SysFreeString(bstrTest );

std::string -> BSTR 举例如下

std::string name = “nisb”;

_bstr_t bstr_t(name.c_str());

BSTR ret_val = bstr_t.GetBSTR();

————————————————-
转来一篇原理编码的原理:

1:使用CString,要包含文件afx.h,比如在Win32 Console Application中Alt+F7选择Use MFC in a Static Liberary,然后再添加#include就可以使用CString了。

2:WCHAR ch = L’中’;与CHAR ch = ’中’;的区别是第一种使用UNICODE编码,第二种方式一般不经常用到,比如:
WCHAR strA [ 2 ] = { L’中’ , 0 } ;//打开VC的Options菜单,选中Debug选项卡中的Display unicode strings后,可以看到strA的值。
WCHAR strB [ 2 ] = { ‘中’ , 0 } ;

CString strC ;

strC+ = ( ( char * ) strB ) [ 1 ] ;
strC+ = ( ( char * ) strB ) [ 0 ] ;//strC==”中”

3:CString的AllocSysString ( )成员函数;可以方便的把一个字符串转换成UNICODE形式。记得使用完该UNICODE字符串后要调用::SysFreeString()函数释放字符串。

4: CString::AllocSysString ( )或者::SysAllocString得到的字符串并不是普通的UNICODE字符串,它之前的四个字节会存放申请的字符串的长度:

CString strD = ”asdf”;
BSTR strD = strC.AllocSysString( ) ;
long i =* ( ( long * ) strD – 1 ) ; // i == 8;一个UNICDE字符的长度是2字节,所以strD的长度为8个字节。

4:UTF-8码转换为一般的字符串:

#include ” Windows.h ”

int main(void)
{
char str [ 256 ] = {( char )0xE4, ( char ) 0xBD, ( char ) 0xA0, ( char ) 0xE5 ,
( char)0xA5 ,(char)0xBD, (char)0x61, (char)0x62 ,(char)0x63,(char)0} ; //一段UTF-8编码
WCHAR* strA;
int i= MultiByteToWideChar ( CP_UTF8 , 0 ,(char*) str ,-1 ,NULL,0);
strA = new WCHAR[i];
MultiByteToWideChar ( CP_UTF8 , 0 ,( char * ) str, -1, strA , i );
i= WideCharToMultiByte(CP_ACP,0,strA,-1,NULL,0,NULL,NULL);
char *strB=new char[i];
WideCharToMultiByte (CP_ACP,0,strA,-1,strB,i,NULL,NULL);
//strB即为所求
delete []strA;
delete []strB;
return 0;
}

5:在转换方面_bstr_t是最最灵活的,他提供了UNICODE到一般字符串的直接转换:
#include
_bstr_t strA;
char *strB=”中国人”;
strA=strB;
WCHAR *strC=strA;
long i =* ( ( long * ) strC – 1 ) ;// i 亦是字符串的字节长度
char *strD=strA;
return 0;

宽窄字串转换!
两种方法:1、CString 2、_bstr_t

#include “comutil.h”
//注意在Project-》Setting-》Link中加入comsupp.lib,从而使_bstr_t可用

void CAaaDlg::OnButton1()
{
// TODO: Add extra cleanup here
_bstr_t a(L”sdfsafds”);
a+=”zzz”;
char * b = (char *)a;//获得内部BSTR的char*指针,勿做修改和释放
WCHAR *c=(WCHAR *)a;//获得内部BSTR的WCHARr*指针,勿做修改和释放
CString p = L”asdfsa”;
p+=”ppp”;
WCHAR *y =p.AllocSysString(); //获得WCHAR*指针,使用完请释放,否则有内存泄漏。
char *z = p.GetBuffer(p.GetLength()+1);//内部Buffer指针,z不要释放

::SysFreeString(y);
}

.net应用odp.net小记

一,下载ODAC112040Xcopy_64bit并解压,在OTP里找。
在cmd中执行>install.bat odp.net4 d:\driver4oracle11.2 odac

odp.net4————你想部署的driver,本人使用.netframework4,不是asp.net和.net2,所以,没用使用All和指定的其它选项。
d:\driver4oracle11.2————你要部署的目标客户机的oracle_home,当然在windows下就加入它到系统环境变量path中。
odac————当在同目录有多个driver时,可以区别吧,反正,因为加了它,可能会报错。但不影响使用。
[true]———-可选的,默认值,即把odp.net依赖的instantclient安装,当你加false时,不装依赖且考虑和已经存在的新版本oracle或现有的环境配合。

当执行了上面的命令后,instantclient(即被odp.net依赖的)也一并从压缩包中被抽取,拷安装到了oracle_home目录中。

二,然后就是设置tnsnames.ora文件。从服务端上相应位置拷过来,放置到home目录中。顺便执行下*access.dll同目录中的oraprovcfg.exe,它是用于注册系统环境变量的。虽然上面已经配置好了,多来一次也无妨。

三,开始客户端程序的开发吧,把home路径中的Oracle.DataAccess.dll拷到项目的debug,和exe同级下面,并在VS中引用,加入using行:
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
代码示例:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;

namespace odp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

}

private string strConn = “Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = ohala-PC)(PORT = 1521))(CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = XE)));”+
“User id=JINGHU;Password=JINGHU;” ;
public void initDBConn()
{
try
{
using(OracleConnection objConn = new OracleConnection(strConn))
{
objConn.Open();
string strSQL = “select * from V_TM_SEGMENT_CFG where SEGMENT_CODE=10 order by STATION_SEQUENCE,TRACK_CODE”;

using(OracleDataAdapter objAdapter = new OracleDataAdapter(strSQL,objConn))
{
//
DataSet ds = new DataSet();
objAdapter.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
//dataGridView1.
dataGridView1.Show();
}

//using (OracleCommand objCommand = new OracleCommand(strSQL, objConn))
//{
// using(OracleDataReader objReader = objCommand.ExecuteReader())
// {
// while (objReader.Read())
// {
// Console.WriteLine(“segment_code is :” + objReader[0].ToString() + “;station_code is :” + objReader[1].ToString());
// //dataGridView1.DataSource
// }

// }
//}//command
}
} catch(Exception ex)
{

}
}

private void button1_Click(object sender, EventArgs e)
{
initDBConn();
}
}
}

升级win10备忘

首先,接手电脑为win8.1,高兴去在线升级结果发现将会升级成win10家庭版,果断拒绝换路。
然后,策略再选择成把win8.1变成专业版,再online升级,如果再不行,就使用ISO了,( VK7JG-NPHTM-C97JM-9MPGT-3V66T)win10密钥吧。

1)升8再升10
保守治疗先,继续玩win8.1,右键“这台电脑”,在系统属性界面,选 择“获取新版本的Windows的更多功能”或者在控制面板中应该不难找到“向windows8.1添加功能”,然后,又是要输入产品密钥。
在这一步输入专业版的零售密钥,如果是升级到win8专业版,就输入8GDW2-NHD3Y-C79G4-B82C4-6Q4DH,(用的这个)
如果是升级到win8.1专业版,就输入 29NQY-3TDJ2-CPXXD-CHDMY-CWD2Y。
然后,漫长的等待windows update进度。注意,要确认本机是已经被激活的不然会升级不成功,并且是最后才给你结果,说不成功。当然如果是激活的,那么就关闭360,再重启。(本人采用方式)

2)ISO升10
直接点击ISO,win10不用虚拟光驱了,又一群要下岗的同行。但这样安装上的win10可能会出现问题。

3)ISO装10(或者用老毛桃啥的做个U盘,引导安装)
过程中选择不保留原有应用和个人文件夹等,那就没有以前版本的windows,回退都没有路子。