分类目录归档:VC

VC++里4、8、12和16字节的成员指针

背景信息简单提一下……大概就是有两次被这事情坑了,我一直以为它只是一个普通指针的大小,32位下是4字节。

第一次,是在前一家公司的时候,遇到一个应用场景,一个头文件需要同时在C和C++里用,里面存有一个成员函数的指针,和void*一起放在union里,是专门给C++用的;C的话这个地方就用条件编译语句换成单个void*。结果是我离开项目组之后,后面用到这段代码的人发现这个成员指针有的时候比void*大。但是那个时候已经不在组里了,也不知道具体那边应用场景是啥样,最后简单把void*替换成char[32]了事,更多的也没在意。

第二次,是在现在这家公司的时候,有个同事在某个头文件里定义的类里面包含了另一个类的成员函数指针,结果这个头文件在两个不同的cpp文件里包含,这个类的大小是不一样的……访问成员变量的时候偏移也不同,数据就坏了。但是cpp里头文件包含的顺序调换一下就能好……同事说是那个成员函数指针的大小会不同,不过那会儿工作有点忙,结果是没放在心上,后来就忘了这事儿了。

最后一次是网友Advance在代码开了最高警告级别的时候,有一个成员指针被报没有对齐到16字节边界,然后就怀疑这个指针的大小。我突然想起之前同事的代码在不同文件访问变量所用的偏移不同的事情,就打算简单调查一下。

继续阅读VC++里4、8、12和16字节的成员指针

VC++中多重继承的指针转换

C++是支持多重继承的。不是像其他一些面向对象语言那样是“一个类实现多个接口”,而是真的多重继承。C++又是能从源代码生成机器码的语言,这种情况下,就要使得 在某个类的指针上调用对象的方法或访问成员变量(不管这个指针指向的就是这个类或者是这个类的子类)都能用同样的机器码实现,就会出现同一个对象,在用不同类型的指针表示它的时候,指针变量保存的地址会不同。它是把一个这样的对象分成几个部分,每个部分都是一个完整的父类型代表的对象,这样当父类型指向对应部分的时候,就能够完全像对待父类型的对象那样对待它。比如有类A和B,然后C同时继承了A和B,那么在C对象的内存空间里,就会有一块可以用A*指,还有另一块可以用B*指。

继续阅读VC++中多重继承的指针转换

WDK编译boost(1.34.1)::regex

Windows Driver Kit里面的STL库啊啥的,基本是停留在VC6时代。不过也有一个好处,可以链接到msvcrt.dll、msvcp60.dll,因为这两个文件大家都有,所以可以减小最后生成的可执行文件的体积。然后比起VC6.0,WDK可以直接从微软那边下载来,而VC6直到最后也没像2005、2008、2010、2012、2013那样有个Express的免费版啥的。于是如果想自己弄了简单的小东西如果想要体积小、要链接到msvcrt.dll,感觉WDK是一个挺好的选择……

继续阅读WDK编译boost(1.34.1)::regex

WindowsDDK里用std::wstring的问题

今天晚上尝试帮某网友制作一个伪春菜的插件,能够检查两次调用过程中剪贴板里面的东西有没有变化(用GetClipboardSequenceNumber函数)和获取剪贴板里的内容(EnumClipboardFormats和GetClipboardData)。这里都不是重点,重点是我用了 这一篇博客 里面提到的CSaori库来编写。这个库里面的字符是wchar_t类型,这很好,也用了std::basic_string<wchar_t>(其实就是std::wstring),这也很好。不好的地方在于,我为了减小最终DLL的体积、用Windows Driver Kit里面的编译器来编译程序使得动态链接到运行库的时候,报错了。

继续阅读WindowsDDK里用std::wstring的问题

VC自制COM组件

Com组件这东西实在是麻烦,以前也一直没有碰过。

过程是这样子的,一天在百度知道上看到有人求助一段C++代码转成VB。我又不熟悉VB,于是就顺手给封装成DLL给了他。

然后提问者回复说,能不能给搞成能用CreateObject方式创建对象的那种方式来调用。这一看,应该要com吧?但是我不会写com。想着稍微掌握一点以后可能也能用到,就去找教学啥的稍微尝试一下。

主要参考的文章是 http://icodeguru.com/VC%26MFC/InsideAtl/ch02c.htmhttp://www.codeguru.com/cpp/com-tech/activex/tutorials/article.php/c5567/Step-by-Step-COM-Tutorial.htm 这两篇。一开始是看后者,后面也看了前者,结合起来,大概理清一点思路了。

继续阅读VC自制COM组件

VC里Tab控件页面的子窗体确定尺寸

果然问题就是在英语不好。msdn虽然有说但是看得实在是……

.net倒是很方便,直接控件拖拖拖,这个都给你实现了的。

但是sdk或者mfc里就比较麻烦。Tab控件上面的页面如果切换了,不是里面的内容要跟着变吗?但是tab控件不管里面的内容变,它只管发一个通知给你。怎么变你自己实现。于是最方便的方法就是弄很多子窗口,在切换的时候更换子窗口。

其实就是你先GetClientRect一下拿到它整个的矩形区域,然后TabCtrl_AdjustRect把这“整个”转换成“里面”。之后你去创建子窗口就可以了。

那个TabCtrl_AdjustRect说真的确实是早就看到了,但是它的说明看得半懂不懂。

VC编写的本地代码程序使用XP Style

只是避免在鱼龙混杂的网络上找到莫名其妙不可靠资料的担忧

msdn上有,不过临时去翻msdn挺麻烦的,因为没记住在哪个分类里面的话(汗

分类在Windows Desktop App Development——Windows Application UI Development——Windows Controls——Visual Styles——Enabling Visual Styles

然后若遇上网络很慢,要人命

继续阅读VC编写的本地代码程序使用XP Style

使用VS2012编译XP上运行的程序

在微软发布了那个升级包之后,编译器toolset里面有了一个Visual Studio 2012 – Windows XP可以选。但是本人使用测试之后,发现旧的工程选了这个toolset以后,编译出来的程序仍然无法在XP上运行。

今天在某个QQ群聊天的时候,SAPikachu大大提到了这个问题,于是我就说我自己试的时候,失败了,编译出来的东西XP不能跑。不过对方测试之后发现,他那边可以。这里面一定有什么设置不对……

对比了以后,发现除了cl.exe编译命令行那边多了一个_USING_V110_SDK71_的宏定义以外,link.exe那边也多了个/SUBSYSTEM:CONSOLE",5.01"参数。但是很奇怪的是,我这里没有。

经过对方提醒,工具集选了v110_xp以后,这个参数是自动加上的才对。我检查了链接器设置那边,发现确实最低版本写了个5.01,但是上面子系统没有填,结果最后的命令行里面没有这个参数。

最后我把子系统那边选了个Console以后这参数就加上去了。虽然还没真正测试过,不过目测这下编译出来的东西可以在windows xp上运行了。

p.s. xp还真是长命w