Just take a record. The purpose is to find a GDI+ replacement library.

a) CxImage
http://www.xdp.it/cximage.htm
Many image formats are supported. It can be used seamlessly under windows with SDK/MFC. Its main disadvantage is that its support for linux is poor. Version 6.0 does not have linux source packages. While with version 5.99, I can only use it to convert between image formats.

b) FreeImage
http://freeimage.sourceforge.net/
Like CxImage, is supports many image formats. Since it focus on image shift and manipulation, how to display a image under windows/linux is not issued. There IS a FAQ to tell windows user how to draw images using GDI. But images with alpha channel(like png) is not displayed normally.

c) ImageMagick
http://www.imagemagick.org/
A console application to manipulate images. It also provides API for programming, but not displaying.

d) cairo
http://cairographics.org/
It’s a powerful cross-platform graphics engine. GTK+ use it to render the majority of its widgets. Firefox and SWT/linux also use it. It can be used as a substantiation for GDI+ under windows. But image format support is limited. Only png can be loaded only with this library.

e) DevIL
http://openil.sourceforge.net/
Formerly known as “OpenIL” and takes role as a cross-platform image library. It has a high rating at sourceforge. However, I was not able to compile its samples using visual studio. They are broken maybe. Skip.

f) wxWidgets
http://wxwidgets.org/
I wonder why so many excellent image/graphics libraries have insufficient feature. Finally, I found that since a image will be display on a DC(Device Context in GDI) or GC(Graphics Context in X11), a cross-platform display media is also needed. Then I continued to search for light-weight cross-platform GUI libraries and turned to wxWidgets.
wxWidgets is simpler than Qt. It can display bmp/jpg/png/tiff images and fills my requirements.

g) Juce
http://www.rawmaterialsoftware.com/juce/index.php
It’s a surprise that I finally knew Juce. From Spy++ tool under windows, I found that all controls of the toolkit is drawn by self, say, they do not use native windows controls and do not have handles like Qt. But it’s much simpler than Qt and contains a UI designer to generate ready-to-compile C++ code. Here’s a demo I created with designer:

You may also see a shadow under the window like Macintosh 🙂
The only issue is that it has a GPL license. haha !

今天开始, 所有的技术文尽量全部用e 文! @@

I don’t really know the exact difference between “transparency” and “translucency”. But the flowing pictures of my running application may show you.

Pic-1 shows a normal dialog with gradient background filled. Pic-2 add opacity ability to the whole dialog(transparent). While Pic-3 only add opacity to the dialog’s background(per-pixel, translucency).

If you’re using windows sdk, there’s an API called “SetLayeredWindowAttributes” to realize the function in Pic-2. You can also call it with a transparency color key to make all pixels of this color to be transparent. But, how to realize the function in Pic-3? My dialog’s background is in gradient color. As mentioned here(in Chinese): To realize it, you must use an API called “UpdateLayeredWindow”. And it’s quite troublesome.

There are also GUI libraries to fill this requirements: 1) WPF, 2) Qt. My application is written in Qt. How do WPF and Qt implement this feature? By drawing all controls themselves. They do not use native windows controls. So if you do it yourself, what a big project !

Using Qt, I call QWidget::setWindowOpacity() to set whole transparency of a window(Pic-2). Qt 4.5 is just released. There’s a new translucency attribute in QWidget class. I use it to realize per-pixel alpha blending(Pic-3). Here’s Sample code:

The demo project can be found here. Note:
a) Make sure you have Qt 4.5 installed to build the project.
b) The translucent window’s type should be set to Qt::FramelessWindowHint.

额.. 又漏了…

这次是GDI+ 的调用引起的, 看代码吧:

主要问题在于Graphics 那个对象. 实际上当前代码的SelectObject() 调用是错误的, 结果就是HBITMAP 对象又泄漏了. 解决的办法就是Graphics 对象用完了就删掉, 就不会锁住里面的HBITMAP 对象了. 方法有2 种: 1) 加一个作用域, 就是把上面的注释去掉. 2) new 一个Graphics 对象, 用完了直接delete 掉.

发现GDI+ 虽然封装了一些比较好用的函数, 但是很容易出错, 而且performance 也不太好. 以后还是少用为妙.

第一篇技术文…

内存泄漏, 句柄泄漏.. windows 编程中最头痛的事情. windows 提供了查看内存检测内存泄漏的API, 却没有提供检测句柄的, 至少我不知道. 第三方的工具如BoundsChecker 倒是异常强大.实在不行并且看得懂nc 堆栈信息的话, 可以用用看M$自家的 AppVerifier .

今天碰到的问题很诡异. 在用工具检查完GDI 句柄泄漏之后, 跑了一上午某个绘图程序, 内存居然涨到了100+M, ft 啊. 于是代码一段段注掉, 找到底哪里漏了… 最后定位到这样的一段代码:

问题在于, 最后的DeleteObject() 调用不正确. 应改为如下:

就是说, 一个HBITMAP 跟一个HDC 还有关联的时候, 不要调用DeleteObject(), 而应该先把原始的HBITMAP 句柄SelectObject() 还原回去. 有以下几条notes:

  • Bitmaps must be disconnected from a DC before being freed.
  • Menus must be freed before an application exits if the menu is not connected to any window.
  • A DC must be disconnected from bitmaps before being freed.
  • If a bitmap is specified for the Caret, it must be freed.
  • Calls to DeleteObject do not harm stock objects.

深愛
水樹奈々

雪が舞い散る夜空
二人寄り添い見上げた
繋がる手と手の温もりは とても優しかった

淡いオールドブルーの
雲間に消えて行くでしょう
永遠へと続くはずの あの約束

あなたの側にいるだけで
ただそれだけでよかった
いつの間にか膨らむ
今以上の夢に気付かずに

どんな時も どこにいる時でも
強く強く抱きしめていて
情熱が日常に染まるとしても
あなたへのこの想いはすべて
終わりなどないと信じている
あなただけずっと見つめているの

交わす言葉と時間
姿も変えて行くでしょう
白い頬に溶けたそれは 月の涙

行かないで もう少しだけ
何度も言いかけては
また会えるよねきっと
何度も自分に問いかける

突然走り出した
行く先の違う二人
もう止まらない
沈黙が想像を越え引き裂いて
一つだけ許される願いがあるなら
ごめんねと伝えたいの

いくら思っていても届かない
声にしなきゃ 動き出さなきゃ
隠したままの二人の秘密
このまま忘れられてしまうの
だからね早く 今ここに来て

あなたの側にいるだけで
ただそれだけでよかった
今度巡り会えたら
もっともっと笑いあえるかな?

どんな時も どこにいる時でも
強く強く抱きしめていて
情熱より熱い熱で溶かして
あなたへのこの想いはすべて
終わりなどないと信じている
あなただけずっと見つめているの

深愛
水樹奈奈

雪花飞舞的夜空
我们两人并肩仰望
紧系著的手和手的温暖 非常的和善

在淡薄蔚蓝的
云彩间隙裏消逝了的吧
本应该永远持续的 那个约定

只要守候在你的身边
仅仅如此就心满意足了
不知何时已膨胀起
穿越现实的梦而我却没有察觉

无论身处何时人在何方
我们都能紧紧的互相拥抱
尽管这份热情将生命映的火红
对於你的这个感情就是一切
并坚信著不会有终结的一天
仅仅只有你是我一直想要注视的

交錯的說話與時間
形貌都會改變
在雪白的臉頰上溶化的 月亮的眼淚

請不要走 多留一會吧
無數次欲言又止
一定會再相見吧
無數次自問

突然踏上路途
目的地不同的兩人
已經無法阻止
沉默超越想像
如果只能實現一個願望
想跟你說對不起

單是心裏想 怎樣也不能傳達
要說出口 要行動
再這樣下去
兩人之間隱藏的秘密就要被忘掉
所以請你現在快點來這裏

只要守候在你的身边
仅仅如此就心满意足了
下次跟你碰面的時候
可以相視而笑嗎?

無論何時 無論身處何地
都想你緊緊抱着我
溶掉比熱情更熾熱的熱度
對你的思念就是一切
至今仍相信不會終結
只想永遠注視你