1. 下载gdi+的sdk,安装。当然,可以简化一点,从这里[ http://download.csdn.net/down/1645798/huohuo1120 ]下载gdiplus所需文件包,解压并导入到vc6(将include和lib目录加入vc6的配置中)
2. 在VC6中创建一个Win32 Application,选择“一个简单的Win32程序”。假设项目名是main
3. 在StdAfx.h中加入
4. 在main.cpp的WinMain前面生命全局的两个GDI变量
5. 在程序退出之前的地方加上
6. 画图
6.1 创建一个Bitmap对象
6.2 从Bitmap中获取Graphics对象
6.3 使用各种东西的组合来搞g,比如Pen, Brush, Region, Rect, PointF, Font……
7. 保存文件,这个比较麻烦
2. 在VC6中创建一个Win32 Application,选择“一个简单的Win32程序”。假设项目名是main
3. 在StdAfx.h中加入
#include <winbase.h>
#define UNICODE
#include <comdef.h>
#ifndef ULONG_PTR
#define ULONG_PTR unsigned long*
#include <GdiPlus.h>
using namespace Gdiplus;
#endif
#define UNICODE
#include <comdef.h>
#ifndef ULONG_PTR
#define ULONG_PTR unsigned long*
#include <GdiPlus.h>
using namespace Gdiplus;
#endif
4. 在main.cpp的WinMain前面生命全局的两个GDI变量
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
ULONG_PTR gdiplusToken;
5. 在程序退出之前的地方加上
GdiplusShutdown(gdiplusToken);
6. 画图
6.1 创建一个Bitmap对象
Bitmap *pBitmap = new Bitmap(width, height, PixelFormat24bppRGB);
6.2 从Bitmap中获取Graphics对象
Graphics *g = Graphics::FromImage(pBitmap);
6.3 使用各种东西的组合来搞g,比如Pen, Brush, Region, Rect, PointF, Font……
Pen pen_black(Color(255, 0, 0, 0), 3);
g->DrawLine(&pen_black, 0, 0, 100, 100);
更具体的说明和各种例子可以在这里找到:GDI+ SDK参考(翻译版本) http://download.csdn.net/source/642128g->DrawLine(&pen_black, 0, 0, 100, 100);
7. 保存文件,这个比较麻烦
bool GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num, size;
Gdiplus::GetImageEncodersSize(&num, &size);
Gdiplus::ImageCodecInfo* pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);
bool found = false;
for (UINT ix = 0; !found && ix < num; ++ix) {
if (0 == _wcsicmp(pImageCodecInfo[ix].MimeType, format) == 0) {
*pClsid = pImageCodecInfo[ix].Clsid;
found = true;
}
}
free(pImageCodecInfo);
return found;
}
......
CLSID encoder;
GetEncoderClsid(L"mime/bmp", &encoder);
pb->Save(L"result.bmp", &encoder, NULL);
{
UINT num, size;
Gdiplus::GetImageEncodersSize(&num, &size);
Gdiplus::ImageCodecInfo* pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);
bool found = false;
for (UINT ix = 0; !found && ix < num; ++ix) {
if (0 == _wcsicmp(pImageCodecInfo[ix].MimeType, format) == 0) {
*pClsid = pImageCodecInfo[ix].Clsid;
found = true;
}
}
free(pImageCodecInfo);
return found;
}
......
CLSID encoder;
GetEncoderClsid(L"mime/bmp", &encoder);
pb->Save(L"result.bmp", &encoder, NULL);
在ISO C规范中有有一个很诡异的东西,那就是传说中的errno,一个有左值的int。当库函数出错的时候,它很可能会被设置为非0值;且没有任何一个库函数或系统调用会把它置为0。
刚接触到errno,可能会认为这是个在errno.h中用
幸而,ISO C并没有规定,errno必须是一个int,如果看errno的manpage (man errno) 会看到:实际上GNU的glibc也就是这么实现的,(通常)在/usr/include/bits/errno.h里头:
于是errno就是个有左值的int了。至于这个__errno_location,在glibc的源码的 csu/errno-loc.c 里头:
而这里的真正的errno,在 csu/errno.c 里头:
由于包含的都是errno.h,所以对于用户程序而言,可见的只有errno.h中的"errno",实际上是(*(__errno_location()),而__errno_location()返回的是errno.c中的errno的地址。可真绕啊。可是偏偏又不能把 __thread int errno; 放在errno.h中,为什么呢?其实原因很简单也很复杂——C语言真是个纠结的语言。
最后,解释一下“__thread”修饰符:__thread defines number to be a thread local variable. 定义thread-local的变量。详情参见Thread-local_storage的wiki页:http://en.wikipedia.org/wiki/Thread-local_storage
刚接触到errno,可能会认为这是个在errno.h中用
int errno;
定义的整型。但是一旦开始写多线程的程序,再看到errno的时候,就会抑郁了。如果两个线程调用库函数都出错,那errno怎么办...?幸而,ISO C并没有规定,errno必须是一个int,如果看errno的manpage (man errno) 会看到:
引用
errno may be a macro. errno is thread-local; setting it in one thread does not affect its value in any other thread.
#define errno (*__errno_location ())
于是errno就是个有左值的int了。至于这个__errno_location,在glibc的源码的 csu/errno-loc.c 里头:
int *
#if ! USE___THREAD
weak_const_function
#endif
__errno_location (void)
{
return &errno;
}
#if ! USE___THREAD
weak_const_function
#endif
__errno_location (void)
{
return &errno;
}
而这里的真正的errno,在 csu/errno.c 里头:
__thread int errno;
由于包含的都是errno.h,所以对于用户程序而言,可见的只有errno.h中的"errno",实际上是(*(__errno_location()),而__errno_location()返回的是errno.c中的errno的地址。可真绕啊。可是偏偏又不能把 __thread int errno; 放在errno.h中,为什么呢?其实原因很简单也很复杂——C语言真是个纠结的语言。
最后,解释一下“__thread”修饰符:__thread defines number to be a thread local variable. 定义thread-local的变量。详情参见Thread-local_storage的wiki页:http://en.wikipedia.org/wiki/Thread-local_storage
纯粹记录一下。看不懂的绕行吧..
当客户端COMMIT成功以后,post-commit会被执行,调用时会传入两个参数,$1是repos的绝对路径,$2是REV,此次提交的版本号。
可以配合rsync用于分发各种东西。
$ mkdir repos
$ svnadmin create repos
$ ls repos/
conf db format hooks locks README.txt
$ ls repos/hooks/
post-commit.tmpl post-revprop-change.tmpl pre-commit.tmpl pre-revprop-change.tmpl start-commit.tmpl
post-lock.tmpl post-unlock.tmpl pre-lock.tmpl pre-unlock.tmpl
$ cd repos/hooks
$ cp post-commit.tmpl post-commit
$ chmod +x post-commit
$ vi post-commit
……
$ svnadmin create repos
$ ls repos/
conf db format hooks locks README.txt
$ ls repos/hooks/
post-commit.tmpl post-revprop-change.tmpl pre-commit.tmpl pre-revprop-change.tmpl start-commit.tmpl
post-lock.tmpl post-unlock.tmpl pre-lock.tmpl pre-unlock.tmpl
$ cd repos/hooks
$ cp post-commit.tmpl post-commit
$ chmod +x post-commit
$ vi post-commit
……
当客户端COMMIT成功以后,post-commit会被执行,调用时会传入两个参数,$1是repos的绝对路径,$2是REV,此次提交的版本号。
可以配合rsync用于分发各种东西。
前一阵和momo讨论到他的基于UDP的某个系统的设计时遇到这样一个问题:在一个局域网中有多台机器,有个消息是通过UDP广播发出的,且每台机器有多个进程需要监听同一个UDP端口,应该怎么办?
由于所知有限,当时我给的解决方案是,使用类似observer模式来建立一个稍复杂的服务(其实就是个转发,但是UDP进程数量未知)。后来momo发现,其实只要通过setsockopt设置SO_REUSEADDR属性之后,多个程序就可以绑定同一个端口了。
虽然问题是解决了,但是SO_REUSEADDR并没有上面提到的那么简单,因为momo遇到的问题正好是UDP广播/多播。否则上述模型就不适用了。这里有一篇文章,对其有更详细的注解,虽然是摘自《UNIX网络编程》的,但是给出了例子,很值得学习。
SO_REUSEADDR例解:http://www.cppblog.com/ace/archive/2006/04/29/6446.aspx
unix网络编程 第一卷:http://wenku.baidu.com/view/99a6cc38376baf1ffc4fad6f.html
由于所知有限,当时我给的解决方案是,使用类似observer模式来建立一个稍复杂的服务(其实就是个转发,但是UDP进程数量未知)。后来momo发现,其实只要通过setsockopt设置SO_REUSEADDR属性之后,多个程序就可以绑定同一个端口了。
虽然问题是解决了,但是SO_REUSEADDR并没有上面提到的那么简单,因为momo遇到的问题正好是UDP广播/多播。否则上述模型就不适用了。这里有一篇文章,对其有更详细的注解,虽然是摘自《UNIX网络编程》的,但是给出了例子,很值得学习。
SO_REUSEADDR例解:http://www.cppblog.com/ace/archive/2006/04/29/6446.aspx
unix网络编程 第一卷:http://wenku.baidu.com/view/99a6cc38376baf1ffc4fad6f.html
昨天去了一趟百度大厦。是从城铁西二旗下车走过去的,方向跟1.26号离职时正好相反。还记得那天的天空,当我走出百度大厦的时候,背后是不那么暖的太阳,抬头是清冷的月亮。跟上一次也反过来的,是在前台登记的时候,我和阿牛的名字在来访者和被访者的位置上对调了,我也贴上那个Baidu Friend的胸贴。到F3-CE去转了一下,没有看到加班的同事,不过上次离开时留下的魔方还在,以及工位上一只不能用的水性笔,挂着的“百年好合”——同事结婚时发的很精致的喜糖包装。把魔方拧好。
预期的中午是个简单的小聚,和阿牛、Sandy聊聊天。不过最后有7个人,包括Kid、Maner,计科8的Ding同学,以及cs研的一位师兄。Sandy还提了一个小蛋糕过来,说是要为我补过生日(情何以堪...)。在辉煌国际的一家快餐店,以比较便宜的价格吃得很开心。蛋糕比较神奇,除了上面用果酱(?)涂写的felix之外,正好有七朵奶油花,七个人。于是蛋糕切起来就很容易了。
下午在阿牛的工位上坐了一会儿,执行来百度大厦的主要目标之一:拷电影。上次离职前从电影协会的FTP里拷了好多电影,每一部都很经典。可惜电影协会的FTP已经换了,此Mission暂时搁置。给阿牛的X201测了3DMark2001,得分8700+,集显。顺便给我的本本也测了一下,9500+,独显……
近四点,HJ也过来了。此行的另一个主要目的,和HJ、Maner打球吃饭。于是到1L去打乒乓球。在中央空调的机器下面,风好大。不过还是打得很开心。其实还是第一次在百度大厦打乒乓球,虽然在里头2个多月……脱了凉鞋,那里的地板脚感很好。然后到汉王那边的蜀香阁,点了几样菜。下午过的很开心。
晚上去参观阿牛的住处。回龙观,龙博苑。离地铁站还算近。房子有点儿旧,不过还算宽敞,家具齐全。挺好。晚上借宿一宿,那个席梦思上没有铺床单,跟我当时在天露园住得一样。
有时候……生活挺单调的,挺混乱的。需要一点调剂,一些慰藉。
预期的中午是个简单的小聚,和阿牛、Sandy聊聊天。不过最后有7个人,包括Kid、Maner,计科8的Ding同学,以及cs研的一位师兄。Sandy还提了一个小蛋糕过来,说是要为我补过生日(情何以堪...)。在辉煌国际的一家快餐店,以比较便宜的价格吃得很开心。蛋糕比较神奇,除了上面用果酱(?)涂写的felix之外,正好有七朵奶油花,七个人。于是蛋糕切起来就很容易了。
下午在阿牛的工位上坐了一会儿,执行来百度大厦的主要目标之一:拷电影。上次离职前从电影协会的FTP里拷了好多电影,每一部都很经典。可惜电影协会的FTP已经换了,此Mission暂时搁置。给阿牛的X201测了3DMark2001,得分8700+,集显。顺便给我的本本也测了一下,9500+,独显……
近四点,HJ也过来了。此行的另一个主要目的,和HJ、Maner打球吃饭。于是到1L去打乒乓球。在中央空调的机器下面,风好大。不过还是打得很开心。其实还是第一次在百度大厦打乒乓球,虽然在里头2个多月……脱了凉鞋,那里的地板脚感很好。然后到汉王那边的蜀香阁,点了几样菜。下午过的很开心。
晚上去参观阿牛的住处。回龙观,龙博苑。离地铁站还算近。房子有点儿旧,不过还算宽敞,家具齐全。挺好。晚上借宿一宿,那个席梦思上没有铺床单,跟我当时在天露园住得一样。
有时候……生活挺单调的,挺混乱的。需要一点调剂,一些慰藉。
记总收益为T,价格为P,售出量为Q,则 T = P * Q。如果P上升10%,Q下降10%,那么T应当如何变化?
答:不变。
---分割线 以上是问题---
第一次看到这个的时候很郁闷,110%P * 90%Q 显然应该是0.99T < T,怎么会不变呢?昨天在看到经济学原理第四章的时候又遇到了中点法计算比例,突然茅塞顿开。
中点法计算比例:假设价格由P1变化到P2,通常我们会用(P2 - P1) / P1 * 100%来计算变动的比例;如果由P2变动到P1,则是(P1 - P2) / P2 * 100%。由于分母变了,分子不变,所以看起来应该是没啥区别的变动,反映到变动比例的时候差别就很大了。比如3->4是33.33%, 4->3是25%,多纠结。于是经济学中通常采用这样的计算方法:这样如论从哪个方向变动,比例都是固定的了。
回到最上面的问题,如果P下降了10%,实际上,下降后的P1 = P * 9/11,Q上升了10%,则Q1 = Q * 11/9。所以T1 = P1 * Q1 = P * Q = T。总收益果然不变。
p.s. (P - P1) / ((P + P1) / 2) = 10% ==> P1 = P * 9 / 11
答:不变。
---分割线 以上是问题---
第一次看到这个的时候很郁闷,110%P * 90%Q 显然应该是0.99T < T,怎么会不变呢?昨天在看到经济学原理第四章的时候又遇到了中点法计算比例,突然茅塞顿开。
中点法计算比例:假设价格由P1变化到P2,通常我们会用(P2 - P1) / P1 * 100%来计算变动的比例;如果由P2变动到P1,则是(P1 - P2) / P2 * 100%。由于分母变了,分子不变,所以看起来应该是没啥区别的变动,反映到变动比例的时候差别就很大了。比如3->4是33.33%, 4->3是25%,多纠结。于是经济学中通常采用这样的计算方法:
引用
变动比例 = (P2 - P1) / ((P1 + P2) / 2) * 100%
回到最上面的问题,如果P下降了10%,实际上,下降后的P1 = P * 9/11,Q上升了10%,则Q1 = Q * 11/9。所以T1 = P1 * Q1 = P * Q = T。总收益果然不变。
p.s. (P - P1) / ((P + P1) / 2) = 10% ==> P1 = P * 9 / 11





类别: 
